# Question
Title: Using Keyboard library for ISO-UK layout
I am creating a keyboard and the PC I use it with is configured for UK so the keyboard layout it expects is this

I've highlighted the ISO-UK vs ANSI-US differences but the only key I am having real problems with is the backslash key.

My physical layout is actually this (ortholinear "Planck") but it's essentially the same except with two logical layers and variation in positioning.

The above is a fully functional UK-layout keyboard with the exception of the "\\" key.

The sketch I am using is too large and distracting to post here but the following test sketch

```
#include "Keyboard.h"

byte keylist[] = { '`', '2', '3', '\'', '#', '\\' };

void setup() {
  Keyboard.begin();
  delay(1000);

  // unshifted
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(keylist[i]);      delay(100);
    Keyboard.release(keylist[i]);    delay(100);
  }

  Keyboard.press(KEY_RETURN);
  Keyboard.releaseAll();

  // shifted
  for (byte i = 0; i < sizeof(keylist); i++) {
    Keyboard.press(KEY_LEFT_SHIFT);
    Keyboard.press(keylist[i]);
    delay(100);
    Keyboard.releaseAll();
    delay(100);
  }
}

void loop() {
  delay(1000);
}

```

Creates this output (in a Notepad window)

```
`23'£#
¬"£@£~

```

I did try switching focus to a keyboard diagnostic tool - KeyHitter by Elite Keyboards which showed different results

```
12:31.0675 ` (0xDF, BIOS 0x29) DOWN
12:31.0771 ` (0xDF, BIOS 0x29) UP -> 100ms
12:32.0772 2 (0x32, BIOS 0x03) DOWN
12:32.0871 2 (0x32, BIOS 0x03) UP -> 100ms
12:33.0872 3 (0x33, BIOS 0x04) DOWN
12:33.0972 3 (0x33, BIOS 0x04) UP -> 100ms
12:34.0972 ' (0xC0, BIOS 0x28) DOWN
12:35.0072 ' (0xC0, BIOS 0x28) UP -> 100ms
12:36.0072 LShift (0x10, BIOS 0x2A) DOWN
12:36.0082 3 (0x33, BIOS 0x04) DOWN
12:36.0172 LShift (0x10, BIOS 0x2A) UP -> 100ms
12:36.0182 3 (0x33, BIOS 0x04) UP -> 100ms
12:37.0172 \ (0xDE, BIOS 0x2B) DOWN
12:37.0272 \ (0xDE, BIOS 0x2B) UP -> 100ms
12:38.0271 Enter (0x0D, BIOS 0x1C) DOWN
12:38.0273 Enter (0x0D, BIOS 0x1C) UP -> 2ms

```

...

So the Arduino `Keyboard` library translates `'#'` into `shift`+`3` which is unhelpful for UK users but I'm mystified why Keyhitter sees that `'\\'` produces the expected `\` but other programs see it producing `#`! I guess Keyhitter intercepts keystrokes at a lower level than normal applications - for example it correctly shows `Win` being pressed but prevents Windows opening a start-menu.

The result in Notepad is typical of the effect produced in normal applications. So that's probably more relevant.

I can work around the `'#'` producing a `shift`+`3` since `'\\'` produces `#` but how then do I generate a `\`?

# Answer
The USB keyboard protocol has no concept of characters. It doesn't know and doesn't care what character a key represents. Instead each code represents the *location* of the key on the keyboard, and it's down to the software on the computer to map those locations into characters through its own keyboard map.

So the Arduino has to do the opposite when you want to "print" text through the keyboard - convert that text into the locations of the keys on the keyboard. And it does that through the `_asciimap` array in `Keyboard.cpp`.

To use any other keyboard layout than US you need to modify that map so that each ASCII value points to the correct location for that character as defined in your computer's keyboard map.

You can find the list of keyboard location codes (named in this document after the US keycap decals) here (page 53) which you can then use to map any changes.

For example in `_asciimap` a double quote is listed as:

```
     0x34|SHIFT,    // "

```

Which maps to `Keyboard ' and "` in USB. But for UK you want that to be shift-2, which is `Keyboard 2 and @` in a US layout. That entry is hex 1F.

So changing the quote to be a shifted 0x1F should give you the quote you desire:

```
    0x1F|SHIFT, // "

```

You would need to do the same to all other characters that need re-mapping (including ). Some may take a little trial and error to work out what the equivalent key on a UK keyboard is, since some keys are in physically different locations (most notably there is no key to the left of Z on a US keyboard, but there is an extra one to the right of \]).

Unfortunately the Arduino Keyboard library doesn't provide a way for a user to give their own keyboard map. Instead you have to modify the source code of the library itself.
> 3 votes

# Answer
For completeness I am posting this answer. You can produce a UK backslash keystroke event by using something like

```
#define KEY_BSLASH 0xEC

```

This was found rather more empirically than analytically so is not an especially informative result, but it might be of some use to others creating non-ANSI keyboard layouts using Arduinos.
> 2 votes

---
Tags: keyboard, atmega32u4
---


title: Is `millis()` affected by long ISRs?

text:
# Question
Title: Is `millis()` affected by long ISRs?
I have a project that uses timers and interrupts frequently. A lot of CPU time is spent handling ISRs over an extended period of time.

Would this affect code inside the main loop that relies on the millis() function since a significant amount of time is spent processing the ISRs?

# Answer
After some digging around in the core, it seems like Arduino updates `millis()` with a 8 bit timer: it uses overflow with a prescaler value of 64. In simpler terms, it has it set up so a certain piece of code (the ISR) is run approximately once per millisecond on a 16MHz system (and proportionately less frequently on slower clocked systems).

When that ISR is ran, it increments a variable that is used by the `millis()` function.

So, even if some non-interruptable code is being ran for a fraction of a millisecond, it won't matter since the bit for that interrupt vector will still remain set.

However, there is a problem when the ISR is ran less often than it should be triggered. This may be a result of using `noInterrupts()` for an extended period of time or when too many other interrupts are being ran and there is not enough CPU for all of the tasks. If a lot of the other ISRs have a higher *interrupt priorities*, it is possible that the code for the `millis()` may never be ran. In this case, you would have more serious issues than this, but it is something to keep in mind when you're writing code.

The general rule of thumb of ISRs still apply: **keep it short!!!**

Note: if you require extreme accuracy, the built in function isn't the best choice. A RTC is a good idea for long term time keeping.
> 8 votes

# Answer
> Would this affect code inside the main loop that relies on the millis() function since a significant amount of time is spent processing the ISRs?

To put a figure on it for you ...

---

## Frequency of the Timer 0 overflow ISR being called

The code called by the (default) Timer 0 overflow interrupt vector (TIM0\_OVF\_vect) is used by `millis` and `micros` to help return their results. Its purpose is to count Timer 0 overflows.

To get accurate results this ISR must not miss an overflow. The timer is configured to **tick** every 4 µs on a 16 MHz system (because of the prescaler of 64: `64 * 62.5 ns = 4000 ns`) and **overflow** every 1.024 ms (1024 µs) - because it overflows after 256 ticks ( `4 µs * 256 = 1024 µs` ).

Since there is only one overflow flag, if the ISR misses an overflow then both millis and micros will be out by 1.024 ms (or more, if it misses multiple overflows).

To be certain of catching that overflow, the ISR therefore has to be called within 1.024 ms (probably slightly less because of the time taken to enter the ISR, so say: 1 ms).

---

## Interrupt priority

On the Atmega328P (such as used in the Arduino Uno) these are the interrupt vector priorities:

```
 1  Reset
 2  External Interrupt Request 0  (pin D2)          (INT0_vect)
 3  External Interrupt Request 1  (pin D3)          (INT1_vect)
 4  Pin Change Interrupt Request 0 (pins D8 to D13) (PCINT0_vect)
 5  Pin Change Interrupt Request 1 (pins A0 to A5)  (PCINT1_vect)
 6  Pin Change Interrupt Request 2 (pins D0 to D7)  (PCINT2_vect)
 7  Watchdog Time-out Interrupt                     (WDT_vect)
 8  Timer/Counter2 Compare Match A                  (TIMER2_COMPA_vect)
 9  Timer/Counter2 Compare Match B                  (TIMER2_COMPB_vect)
10  Timer/Counter2 Overflow                         (TIMER2_OVF_vect)
11  Timer/Counter1 Capture Event                    (TIMER1_CAPT_vect)
12  Timer/Counter1 Compare Match A                  (TIMER1_COMPA_vect)
13  Timer/Counter1 Compare Match B                  (TIMER1_COMPB_vect)
14  Timer/Counter1 Overflow                         (TIMER1_OVF_vect)
15  Timer/Counter0 Compare Match A                  (TIMER0_COMPA_vect)
16  Timer/Counter0 Compare Match B                  (TIMER0_COMPB_vect)
17  Timer/Counter0 Overflow                         (TIMER0_OVF_vect)
18  SPI Serial Transfer Complete                    (SPI_STC_vect)
19  USART Rx Complete                               (USART_RX_vect)
20  USART, Data Register Empty                      (USART_UDRE_vect)
21  USART, Tx Complete                              (USART_TX_vect)
22  ADC Conversion Complete                         (ADC_vect)
23  EEPROM Ready                                    (EE_READY_vect)
24  Analog Comparator                               (ANALOG_COMP_vect)
25  2-wire Serial Interface  (I2C)                  (TWI_vect)
26  Store Program Memory Ready                      (SPM_READY_vect)

```

You can see from that list that TIMER0\_OVF\_vect is number 17 on that list, so any earlier priority interrupt would take precedence, for example external interrupts, pin change interrupts, the other timers (however not SPI / Serial / ADC / I2C).

If an overflow had **just happened** then you would have practically 2 ms of grace (because you have 1 ms before the next and then another 1 ms before you need to notice it). However if the overflow is **about to happen** then you only have the 1 ms grace period.

I mention this because if you have an external interrupt 0 event (INT0\_vect) and the ISR takes 500 µs, and then external interrupt 1 event (INT1\_vect) during that time (so another ISR will be serviced) then the timer interrupt might be blocked for a while.

That is why **all** ISRs should be short. It isn't good enough that some of them are.

---

## Re-enabling interrupts

I strongly recommend **against** this. The libraries are not designed to be re-entrant, and once you start enabling interrupts in one ISR you may find that it itself is called again when it is half-way through being called the first time. You may also conceivably interrupt a library function (eg. memcpy) that was not designed for it.

And, of course, if you are re-enabling interrupts inside an ISR **because** the ISR takes a long time: well, that is the exact situation when you may trigger this re-entrancy.

---

## More information:
> 3 votes

# Answer
The timer interrupt can even disrupt measurement of pulses using micros() from an on change interrupt. The timer interrupt takes around 6.5us on Arduino Uno or mega. If a change interrupt takes place just after the timer interrupt, then the change interrupt will be delayed by up to 6.5us until the timer interrupt completes. In addition, the microsecond count is only updated once every 4us, introducing further uncertainty up to 4us.

So the measurement may be up to 10.5us out. This should be considered when measuring pulse lengths.
> 2 votes

# Answer
ABSOLUTELY

any ISR that is long will prevent millis() from incrementing. It can be dubiously slow skew of this clock.

The ISR function always start off with blocking interrupts with the cli() command at start and finish by enabling them with the sei() command. Blocking other ISR's along with Timer0's OverFlow interrupt which is used for increamenting the millis counter.

Any extended use of noInterrupts() or cli() or implied use with ISR's should be carefully short in duration. There is no general harm in executing either of interrupts() or sei() with in the ISR, as to allow interrupts again.

Example:

in the VS1053 library I have Data Request on an INT pin. Which's ISR may read from the SdCard, which can take a very long time. So I re-enable the interrupts() before reading the SdCard, but still in the ISR.
> 1 votes

---
Tags: interrupt, millis, isr
---


# Question
Title: Best Data model/Concept to Store Multi-Day Alarm for clock?
I'm writing a multiday day alarm program for a project.

I'm not sure how I want to store the format of each of 10 alarms....I need to store it...in SPIFFS retrieve it(at boot) and then compare it to the current day of the week and time so as to fire off the alarm..I was thinking of storing it in a 10 member array.

First alarm would be every day at 2PM and the second is turned off but would be Mon tues Thursday at 10AM. was going to use strtok\_r to extract all of the pieces and compare them every minutte to see if an alarm is needed.

Every minute

`{"1|M|T|W|T|F|S|S|14|00","0|M|T||T|||S|10|00"}`

# Answer
> 1 votes
I would suggest a bit field for storing the days of the week when the alarm is supposed to fire:

* bit 0: fire on Sundays
* bit 1: fire on Mondays
* ...

This numbering is meant to match the one of `DateTime::dayOfTheWeek()`.

Pack this, together with the hour and minute of the alarm, in a `struct` (or a `class` if you prefer). Maybe add a boolean to tell whether the alarm is active. For example:

```
struct Alarm {
    bool is_on;
    uint8_t days;  // bitfield: 0 = Sunday
    uint8_t hour;
    uint8_t minute;
    bool matches(DateTime) const;
};

bool Alarm::matches(DateTime t) const {
    bool day_matches = days & (1 << t.dayOfTheWeek());
    return day_matches && t.hour() == hour && t.minute() == minute;
}

```

Then `if (alarm.is_on && alarm.matches(rtc.now()))`, the alarm fires.

# Answer
> 1 votes
That would work. Though I feel like your solution isn't easily readable by humans, and also not easily readable by machines.

Removing the `|`s, making the data a fixed length, and putting each alarm on separate line, would help with both. You'd get something like

```
ON  MTWTFSS 14:00
OFF MT T  S 10:00

```

Because the data-string is of a fixed length, you know where the data you want is inside the string. So your code can, for example, check the 7th character, to see if it needs to turn on/off on Wednesday. Or check the 13th and 14th character to get the hour. And so on.

But you'd have to decide what's important to you. Human readability, machine parseability, compactness (storing it as binary data, like Edgar said), standardized format (Cron-style), Extensibility (for example the option to add seconds, somewhere in the future), ease of implementing.

---
Tags: programming, esp32, spiffs
---


# Question
Title: If condition for switch not working as expected
I am trying to write a simple program to control one LED with two switches.

If any of the switches is pressed, I want to turn the LED on.

My LED however is always ON even when none of the switches are pushed. Why could this happen?

Thanks!

https://www.tinkercad.com/things/7SRoEXkHRqh-one-led-two-switches-

# Answer
It's hard to tell which pins of the switch do what. Since you have your inputs set up as INPUT (instead of INPUT\_PULLUP) you should have a resistor (10k Ω, say) tying those pins to ground. Then the other end of switch should connect to +5V. Don't connect the switches to both +5V and ground.

Use a multimeter on continuity to make sure that the pins of the switch that you are using are open normally, and close when you press the switch. With 4 pins it's easy to get confused as to which switch pin does what.
> 1 votes

# Answer
It's easy to confuse the pins of these single-pole buttons - I still do it. Only two pins are needed for this kind of button. The extra two are there for mechanical stability on the PC board.

Lay the button on one of its sides:

* If the two upper pins come out of the top edge, those pins are switched - either open, or shorted by the button. Ditto, for the two bottom pins.
* If instead, the two upper pins come out of opposite edges, those two are literally a *single piece of wire* passing through the button-frame and so are *always* shorted to each other. These two pins together are open with respect to the bottom two pins when the button is released, or shorted to the bottom two pins when the button is pressed.

Update:

> I probably won't remember your info next time I need to use one of these switches, so I'll still have to just test it... :(

Thanks, @Duncan C. I probably made it more complicated than it needed to be! How about:

Each pair of pins is a flat metal strip, bent to pass through the switch body, each end of it pointing down at the PC board; roughly into the shape of the letter 'C'. Looking at one of the pins, there is only one other pin that could be its other end, because you can only bend a flat strip toward one of its faces, not edgewise.
> 1 votes

---
Tags: arduino-uno, arduino-mega, arduino-nano
---


# Question
Title: How to enable exception handling on the Arduino Due?
While the question here gives some hints, the solution provided there does not directly work on the Due, since it uses a different compiler and toolkit. Also, the Due has more than enough flash for most projects, so that the extra code required for exception handling is acceptable. But as with the AVR-based boards, "-fno-exceptions" is automatically added to the compiler flags when using the Arduino IDE, preventing any throw or catch instructions to compile.

How can I enable exception support on the Due?

# Answer
> 5 votes
First, we must make sure the "-fno-exceptions" compiler flag is overwritten with "-fexceptions". In addition, we must link a separate library that includes the compiler support functions for stack unwinding.

Navigate to `C:\Users\<UserName>\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12` and create a new file `platform.local.txt` with this content:

```

compiler.cpp.extra_flags=-fexceptions
linker.elf.extralibs=-lsupc++

recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" -mcpu={build.mcu} -mthumb {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--start-group {compiler.combine.flags} {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group -lm -lgcc {linker.elf.extralibs}

```

The last line should match the corresponding line in `platform.txt`, with an extra `{linker.elf.extralibs}` at the end (upgrading the toolkit might update that line, so you may need to compare the other parameters).

These lines add the `-fexceptions` to the compiler command line and the `supc++` library to the linker input (otherwise you'll get errors about unresolved externals). After these changes, you can rebuild your project and use exception handling.

**Some usage hints**

The exception support on the Due requires about 40k of extra flash memory. Given it has 512k, this is usually acceptable. A bit of extra RAM is also used, but that seems to be small enough as well.

Since there are no standard exception classes defined (and the ArduinoSTL library doesn't compile on the due out-of-the-box), you'll have to write your own exception classes, i.e something like this:

```
class Exception
{
  private:
  const char* _msg;
  public:
  Exception(const char* msg)
  {
    _msg = msg;
  }

  const char* Message() const
  {
    return _msg;
  }
};

```

Use as:

```

void ThrowExceptionFunc()
{
  throw Exception("Something bad happened");
}

void ValidateExceptionHandling()
{
  try
  {
    ThrowExceptionFunc();
    Serial.print("Exception was not thrown:");
  }
  catch(Exception& ex)
  {
    Serial.print("Exception happened:");
    Serial.println(ex.Message());
  }
}

```

Note that **Unhandled exceptions will terminate the program**. An unhandled exception will cause the due to output a corresponding message to the serial console and then enter a deadend fail state.

---
Tags: arduino-due, compilation-errors
---


title: Serial Communication to Control Stepper

text:
# Question
Title: Serial Communication to Control Stepper
\**I wanted to add an updated code after I have finished it to help others in the future if they are ever looking for it.

EDIT AT END OF QUESTION AFTER ANSWER AND CODE UPDATE.\**

I currently have an Uno with a CNCBoard Hat.

I am running a program on my RPi and sending a value through serial to the Arduino. I am receiving what I believe is a string, converting it to an `int` using `toInt()` (I found this solution somewhere). I then want to write that value to the stepper I have connected.

I know the stepper works, because if I run a simple test program such as this one:

```
const int stepX = 2;
const int dirX  = 5;

const int stepY = 3;
const int dirY  = 6;

const int stepZ = 4;
const int dirZ  = 7;

const int enPin = 8;

void setup() {
  // Sets the two pins as Outputs
  pinMode(stepX, OUTPUT);
  pinMode(dirX, OUTPUT);
  pinMode(enPin, OUTPUT);

  digitalWrite(enPin, LOW);
  digitalWrite(dirX, HIGH);
  digitalWrite(dirY, LOW);
  digitalWrite(dirZ, HIGH);
}

void loop() {
  // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation
  for (int x = 0; x < 200; x++) {
    digitalWrite(stepX,HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepX, LOW);
    delayMicroseconds(1000);
  }
   delay(1000); // One second delay
}

```

The stepper rotates as the program describes. Where 200 is the pulse count.

The program I am currently trying to use is:

```
// defines pins numbers
//Front left wheel
const int stepX = 2;
const int dirX  = 5;

//Front right wheel
const int stepY = 3;
const int dirY  = 6;

//Back left wheel
const int stepZ = 4;
const int dirZ  = 7;

//Back right wheel
const int stepA = 12;
const int dirA  = 13;

const int enPin = 8;

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

  // Sets the two pins as Outputs
  pinMode(stepX, OUTPUT);
  pinMode(dirX, OUTPUT);

  pinMode(stepY, OUTPUT);
  pinMode(dirY, OUTPUT);

  pinMode(stepZ, OUTPUT);
  pinMode(dirZ, OUTPUT);

  pinMode(enPin, OUTPUT);

  digitalWrite(enPin, LOW);
  digitalWrite(dirX, HIGH);
  digitalWrite(dirY, LOW);
  digitalWrite(dirZ, HIGH);
  digitalWrite(dirA, HIGH);
}

void loop() {
  String YpulseEncode;
  if (Serial.available() > 0) {
    YpulseEncode = Serial.readStringUntil('\n');
    int yMove1 = YpulseEncode.toInt();
    //XpulseCalc = Serial.read();

    //Serial.print("YpulseCalc: ");
    Serial.println(yMove1 * (-1));
    //Serial.print("YpulseCalc +: ");
    //Serial.println(YpulseCalc
    //Serial.print("XpulseCalc: ");
    //Serial.println(XpulseCalc);
    delay(5000);
    Serial.end();
    if (yMove1 != 0) {
      // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
      for (int x = 0; x < (yMove1); x++) {
        digitalWrite(stepX, HIGH);
        delayMicroseconds(1000);
        digitalWrite(stepX, LOW);
      }
    }
  }
}

```

The number I am receiving from the RPi is -267. So when the serial monitor shows it, it is 267. I want to send the number 267 pulses to the stepper motor.

**EDIT - UPDATED CODE**

```

AccelStepper yStepper(AccelStepper::DRIVER, 2, 5);

// defines pins numbers
//Front left wheel
const int stepX = 2;
const int dirX  = 5;

//Front right wheel
const int stepY = 3;
const int dirY  = 6;

//Back left wheel
const int stepZ = 4;
const int dirZ  = 7;

//Back right wheel
const int stepA = 12;
const int dirA  = 13;

const int enPin = 8;

void setup() {
  yStepper.setMaxSpeed(800);
  yStepper.setAcceleration(400);

  Serial.begin(9600);

  // Sets the pins as Outputs
  pinMode(stepX, OUTPUT);
  pinMode(dirX, OUTPUT);

  pinMode(stepY, OUTPUT);
  pinMode(dirY, OUTPUT);

  pinMode(stepZ, OUTPUT);
  pinMode(dirZ, OUTPUT);

  pinMode(enPin, OUTPUT);

  digitalWrite(enPin, LOW);
  digitalWrite(dirX, HIGH);
  digitalWrite(dirY, LOW);
  digitalWrite(dirZ, HIGH);
  digitalWrite(dirA, HIGH);
}

void loop() {

  String YpulseEncode;
  if (Serial.available() > 0) {
    YpulseEncode = Serial.readStringUntil('\n');
    int yMove1 = YpulseEncode.toInt();

if (yMove1 < 0) {
    int yMoveNew = yMove1 * (-1);

    //XpulseCalc = Serial.read();
    //Serial.print("YpulseCalc: ");
    Serial.println(yMove1 * (-1));
    //Serial.print("YpulseCalc +: ");
    //Serial.println(YpulseCalc
    //Serial.print("XpulseCalc: ");
    //Serial.println(XpulseCalc);
    delay(2000);

      // Enables the motor to move in a particular direction
      // Makes 200 pulses for making one full cycle rotation
      //for (int x = 0; x < yMoveNew; x++) {
      yStepper.move(yMoveNew);
      yStepper.runToPosition();
        //digitalWrite(stepX, HIGH);
        delayMicroseconds(1000);
        //digitalWrite(stepX, LOW);
      //}
    }
  }
}

```

# Answer
> 2 votes
You have 2 problems, which are already mentioned in the comments:

* You call `Serial.end()` after you received one line. That will stop the Serial hardware. Thus the code will only receive one line and then ignore any data from Serial. I don't think, that you want this. So just remove the `Serial.end()`.
* `yMove1` is negative, while your `for` loop has the condition `int x = 0; x < (yMove1); x++`. But zero is always higher than a negative number. Thus the `for` does not run at all (the condition `x < yMove1` is `false`, when `yMove1` is negative). I don't quite understand, why you want to provide a negative number. You don't have any code for direction reversing. In the current state I would suggest just not sending a negative number. I cannot say more, because it is unclear, what exactly you want here.

---

Note:

* The parentheses around `yMove1` inside the `for` loop condition is not needed.
* The `if` statement `if (yMove1 != 0)` is not needed. If `yMove1` is zero, the `for` loop will just not run, because it starts with zero.

---
Tags: arduino-uno, stepper
---


# Question
Title: Does Linux have software protection on USB? Or has the magic smoke escaped?
I'm making a GUI in Python that will control an Arduino via serial monitor. I have 6 input pins grounded and I'm taking 5V from the board (powered from USB) whilst serial monitoring and everything's going beautifully.

I'm so impressed by all these flickering 0's and 1's that I drop my flying lead straight onto the tiny cap behind the USB connector on the UNO. Everything is definitely not going beautifully now. My serial data is frozen mid-string.

I try to connect again with my serial monitor software:

```
Error: Could not open device /dev/ttyUSB0

```

Power off and on my PC and the Arduino, same result. So, I connect another board a nano this time.

The Arduino Web Editor recognizes that I have connected a Nano, but when I try to upload my code the Arduino Web Editor says this:

```
avrdude: ser_open(): can't open device "/dev/ttyUSB0": Permission denied

```

So, I put this in to terminal:

```
sudo chmod a+rw /dev/ttyACM0
chmod: cannot access '/dev/ttyACM0': No such file or directory
sudo chmod a+rw /dev/ttyusb0
chmod: cannot access '/dev/ttyusb0': No such file or directory

```

Thought I might have fried my USB but it's still accepting flash drives being plugged in, and I have connected to both front and back USBs with the same results. And I have power-cycled my PC.

So, not sure if I fried my Arduino, (but having 2 Arduinos with the same fault seems unlikely, especially as one was not attached when I dropped the flying lead).

Magic smoke escaped from my PC USB ports, but again it seems unlikely that front and back would be dead whilst allowing USB sticks to communicate.

Is there some kind of software fusing preventing communication that needs to be/can be reset? Or could something have become corrupted maybe?

I'm on Ubuntu 20. If anyone knows of a command I can give that will bring ttyusb0 back to life, that would be great.

# Answer
The fact that you're referencing `ttyUSB0` tells me you have cheap Chinese clones and not genuine Ardunios. These are usually based around the CH340 USB interface chip which is notoriously unreliable.

Your UNO is dead.

My supposition is that plugging it in cripples the CH340 driver. Any other boards that you subsequently plug in can not be recognised because the driver is in a bad state.

To prove this:

1. Unplug the UNO
2. Reboot (power cycle) the computer
3. Plug in the Nano

It should recognise the Nano fine.

4. Unplug the Nano
5. Plug in the UNO

It should fail now.

6. Unplug the UNO
7. Plug in the Nano

The Nano should now also fail.

If that sequence is correct then the Uno is definitely dead. Throw it away, or at least never plug it in through USB ever again (you could program over serial through the TX/RX pins or using ICSP as if it were a breadboard Arduino though).
> 2 votes

# Answer
running:

`sudo usermod -a -G dialout $USER`

cleared the issue it was the first time I have used that machine with an Aduino not sure how it was running before with out permissions set up correctly or why it failed when I dropped that 5v, I assume that just reset the board and when it tried to reconnect it failed. Both board and PC all working fine, phew.

Thanks
> 1 votes

---
Tags: arduino-uno, serial, linux, ubuntu
---


title: Laser tripwire and LDR

text:
# Question
Title: Laser tripwire and LDR
I am planning to make a laser tripwire but I have an issue. Let me explain what I am trying to do:

Making a laser tripwire is actually pretty easy at its core. You just need an LDR and a laser diode. You look at the normal results of the LDR; it's usually around 60.

When the laser hits the LDR, it's usually around 600 so you write an `if` statement saying if the LDR value is below 500, power the LED or buzzer.

But there is an issue here. The LDR module must be connected to Arduino with cables for signaling. I don't want that. Luckily, I have a Bluetooth module but I have no idea how to use it for sending signal to my Android phone. I know how to send signals though. So to simplify things:

---

Can I send any kind of signal to my phone with Bluetooth (I am using an app called `Arduino Bluecontroll` but I can upload a different app if necessary)? If yes, how?

# Answer
> 1 votes
> Can I send any kind of signal to my phone with Bluetooth?

You have an HC-06, which is a bluetooth Serial (UART) bridge. Thus the bluetooth device exposes the profile for a serial terminal. You can only transmit serial data. It doesn't work for HID input to the smatphone or audio. The Bluecontrol app seems to use serial. So that is not a problem.

To get the communication to work, you need to pair the HC-06 with your phone. The actual connection is then established by the app. It will send serial data to the HC-06, which will output it on its TX pin. Serial communication on its RX pin will be transmitted back to the app.

You need to test, for which baudrate the HC-06 is configured. For that write a test sketch, you use an extra serial interface (either another hardware interface or SoftwareSerial) for the HC-06 and send every byte, that you receive from it, to your PC, so that you can see, what the Arduino receives. Try different standard baudrates (like those, which are listed in the serial monitor), until you find the one, which gives you the correct output.

When that works, you can write your sketch to read the commands from the HC-06 serial interface and act accordingly. How exactly that works depends on the data, that the app is sending. Most likely is sends ASCII encoded text, each message terminated by a newline character `\n`. In that case you could read the data into a buffer byte by byte, when they arrive. When you read a newline character, you know, that you received a full message. Then you can process it and act accordingly.

---
Tags: bluetooth, serial-data
---


# Question
Title: MPU6050 FIFO overflow and freezing problems
I'm using the sensor MPU6050 to control movements of my robotic arm. The code works fine when it is a standalone program but I keep encountering 'FIFO overflow' when the code is compiled into the main program. This is the code that I am using:

```
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>
    #include "I2Cdev.h"
    #include "MPU6050_6Axis_MotionApps20.h"
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif
    MPU6050 mpu;

    RF24 radio(9, 8);  // CE, CSN

    const byte address[6] = "00001";

    const int AccReadings = 10;
    //Wrist Roll
    int DataX[AccReadings];
    int WRIndex = 0;
    int WRtotal = 0;
    int WRaverage = 0;
    //Wrist Pitch
    int DataY[AccReadings];
    int WPIndex = 0;
    int WPtotal = 0;
    int WPaverage = 0;
    //Shoulder Lift
    int DataY2[AccReadings];
    int SLIndex = 0;
    int SLtotal = 0;
    int SLaverage = 0;
    //Elbow Lift
    int ELaverage = 0;
    //Arm Rotation
    int ARaverage = 0;
    float correct;

    #define OUTPUT_READABLE_YAWPITCHROLL
    #define INTERRUPT_PIN 2
    bool blinkState = false;

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

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

    struct Sensor_Data
    {
      int WristRoll;
      int WristPitch;
      int ShoulderLift;
      int ElbowLift;
      int ArmRotation;
    };
    Sensor_Data data;

    //Interrupt Detection
    volatile bool mpuInterrupt = false;
    void dmpDataReady()
    {
      mpuInterrupt = true;
    }

    void setup()
    {
      radio.begin();
      radio.openWritingPipe(address);
      radio.setPALevel(RF24_PA_MIN);
      radio.stopListening();

      //Zero-fill Arrays
      for (int i = 0; i < AccReadings; i++)
      {
       DataX[i] = 0;
      }
      for (int j = 0; j < AccReadings; j++)
      {
       DataY[j] = 0;
      }
      for (int k = 0; k < AccReadings; k++)
      {
       DataY2[k] = 0;
      }

      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        Wire.begin();
        Wire.setClock(400000);
      #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
        Fastwire::setup(400, true);
      #endif

      Serial.begin(115200);
      while (!Serial);

      mpu.initialize();
      pinMode(INTERRUPT_PIN, INPUT);
      devStatus = mpu.dmpInitialize();
      mpu.setXGyroOffset(49);
      mpu.setYGyroOffset(-18);
      mpu.setZGyroOffset(9);
      mpu.setZAccelOffset(4427);

      if (devStatus == 0)
      {
        mpu.setDMPEnabled(true);
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
      }
      else
      {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        // Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
      }
    }

    void loop()
    {
      /*smoothWR();
      movementWR();
      smoothWP();
      movementWP();
      smoothSL();
      movementSL();*/
      ElbowMovement();
      radio.write(&data, sizeof(Sensor_Data));
    }

    void smoothWR()
    {
      WRtotal = WRtotal - DataX[WRIndex];
      DataX[WRIndex] = analogRead(A0);
      WRtotal = WRtotal + DataX[WRIndex];
      WRIndex = WRIndex + 1;

      if (WRIndex >= AccReadings)
      {
        WRIndex = 0;
      }

      WRaverage = WRtotal / AccReadings;
      //Serial.println(WRaverage);
    }

    void movementWR()
    {
      WRaverage = map(WRaverage, 278, 419, 0, 180);
      data.WristRoll = constrain(WRaverage, 0, 180);
      //Serial.println(data.WristRoll);
    }

    void smoothWP()
    {
      WPtotal = WPtotal - DataY[WPIndex];
      DataY[WPIndex] = analogRead(A1);
      WPtotal = WPtotal + DataY[WPIndex];
      WPIndex = WPIndex + 1;

      if (WPIndex >= AccReadings)
      {
        WPIndex = 0;
      }

      WPaverage = WPtotal / AccReadings;
      //Serial.println(WPaverage);
    }

    void movementWP()
    {
      WPaverage = map(WPaverage, 280, 421, 0 , 135);
      data.WristPitch = constrain(WPaverage, 0, 135);
      //Serial.println(data.WristPitch);
    }

    void smoothSL()
    {
      SLtotal = SLtotal - DataY2[SLIndex];
      DataY2[SLIndex] = analogRead(A2);
      SLtotal = SLtotal + DataY2[SLIndex];
      SLIndex = SLIndex + 1;

      if (SLIndex >= AccReadings)
      {
        SLIndex = 0;
      }

      SLaverage = SLtotal / AccReadings;
      //Serial.println(SLaverage);
    }

    void movementSL()
    {
      SLaverage = map(SLaverage, 410, 270, 0 , 180);
      data.ShoulderLift = constrain(SLaverage, 35, 180);
      //Serial.println(data.ShoulderLift);
    }

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

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

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

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

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

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

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

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

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

        // Yaw, Pitch, Roll values - Radians to degrees
        ypr[0] = ypr[0] * 180 / M_PI;
        ypr[1] = ypr[1] * 180 / M_PI;
        ypr[2] = ypr[2] * 180 / M_PI;

        // Skip 300 readings (self-calibration process)
        if (int l = 0; l <= 300) {
          correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
          l++;
        }
        // After 300 readings
        else {
          ypr[0] = ypr[0] - correct; // Set the Yaw to 0 deg - subtract  the last random Yaw value from the currrent value to make the Yaw 0 degrees
          // Map the values of the MPU6050 sensor from -90 to 90 to values suatable for the servo control from 0 to 180
          ELaverage = map(ypr[0], -90, 90, 0, 180);
          data.ElbowLift = constrain(ELaverage, 30, 110);
          ARaverage = map(ypr[1], -90, 90, 0, 180);
          data.ArmRotation = constrain(ARaverage, 0, 180);
          //Serial.println(data.ElbowLift);
          Serial.println(ypr[1]);
        }
    #endif
      }
    }

```

Is there any ways to get rid of the FIFO overflow? Also When I tried to used Jeff Rowberg's example code MPU6050\_DMP6 the program froze after a few seconds. Is there any solution to that?

This is the example code that I am using:

```
    #include "I2Cdev.h"
    #include "MPU6050_6Axis_MotionApps20.h"
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif
    MPU6050 mpu;
    float correct;
    int j = 0;

    #define OUTPUT_READABLE_YAWPITCHROLL
    #define INTERRUPT_PIN 2
    bool blinkState = false;

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

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

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

    void setup()
    {
      #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
      Wire.begin();
      Wire.setClock(400000);
      #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
      Fastwire::setup(400, true);
      #endif
      Serial.begin(38400);
      while (!Serial);

      mpu.initialize();
      pinMode(INTERRUPT_PIN, INPUT);
      devStatus = mpu.dmpInitialize();
      mpu.setXGyroOffset(17);
      mpu.setYGyroOffset(-69);
      mpu.setZGyroOffset(27);
      mpu.setZAccelOffset(1551);

      if (devStatus == 0)
      {
        mpu.setDMPEnabled(true);
        attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
        mpuIntStatus = mpu.getIntStatus();
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
      }
      else
      {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        // Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
      }
    }

    void loop()
    {
      if (!dmpReady) return;
      if (mpu.dmpGetCurrentFIFOPacket(fifoBuffer))
      {
        #ifdef OUTPUT_READABLE_YAWPITCHROLL
                // display Euler angles in degrees
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetGravity(&gravity, &q);
                mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
                if (j <= 300)
                {
                  correct = ypr[0]; // Yaw starts at random value, so we capture last value after 300 readings
                  j++;
                }
                else
                {
                  ypr[0] = ypr[0] - correct;
                  Serial.print("ypr\t");
                  Serial.print(ypr[0] * 180/M_PI);
                  Serial.print("\t");
                  Serial.print(ypr[1] * 180/M_PI);
                  Serial.print("\t");
                  Serial.println(ypr[2] * 180/M_PI);
                }
        #endif
      }
    }

```

# Answer
> 0 votes
I have used an MPU6050 successfully in my autonomous robot project for several years now, so I have some knowledge of the subject

If your code is freezing intermittently, it may well be the infamous bug in the Arduino 'Wire' code that causes the I2C receive and/or transmit functions to block under certain conditions.

Take a look at some of my posts on 'Paynter's Palace'. You'll find there is a long history of intermittent I2C hangup problems with the stock 'Wire' library. The good news is that this problem was (sorta) fixed. You can now use the stock 'Wire' library, but you still have to manually enable the watchdog timeout value to get the transmit/receive functions to unblock if they get stuck.

See this post regarding the Wire library bug fix. You will find the following lines in setup():

```
Wire.setWireTimeout(3000,true);
    wireTimeoutCount = 0;
    Wire.clearWireTimeoutFlag();

```

These lines set a reasonable timeout value (3000 uSec in my case), reset a local variable (wireTimeoutCount) I used for debug, and reset the new Wire library timeout flag.

Note that you'll need to ensure you are using the latest Wire library code. If the above 'Wire.setWireTimout(3000, true);' compiles, then you are using the latest library. If it doesn't, then you'll have to get the latest one.

Hope this helps,

Frank

---
Tags: mpu6050
---


title: defining a macro with variables

text:
# Question
Title: defining a macro with variables
I am working on Marlin 3D program. I made some changes for xyz prop and I do not make a definition as `#define PRB_GCODE_END "G92 X-" XOFF "Y" XOFF "Z" ZOFF "\ n"` to send the final xyz coordinates as gcode at the end of the promulgation procedure. It is required. If anyone has any idea how to use float type variables during macro definition please help.

```
void _user_gcode_exe(const char * const cmd) {
  lcd_return_to_status();
  enqueue_and_echo_commands_P(cmd);
}

void user_gcode_exe_1() {
  float XOFF = (25.00 + PRB_XOFFSET + (TOOL_DIA / 2.00));
  float YOFF = (25.00 - (PRB_YOFFSET + (TOOL_DIA / 2.00)));
  float ZOFF = (10.00 + PRB_ZOFFSET);

#define PRB_GCODE_END "G92 X-" XOFF " Y" XOFF " Z" ZOFF "\n"

#define PRB_GCODE "M117 Z-XY Probing now..\nG38.2 F120 Z-20.00\nG92 X0.00 Y.00 Z0.00\nG0 Z5.00 F1200\nG0 X-20.00 F1200\nG0 Z-5.00 F1200\nG38.2 F120 X25.00\nG92 X0.00\nG0 X-5.00 Y-25.00 F1200\nG0 X15.00 F1200\nG38.2 F120 Y25.00\nG92 Y0.00\nG0 Y-5.00 F1200\nG0 Z10.00 F1200\nG0 X-25.00 Y25.00 F1200\n"

#define MSG__OK "M117 Z-XY Probing done..\n"
  _user_gcode_exe(PSTR(PRB_GCODE PRB_GCODE_END MSG__OK));
}

```

While defining `PRB_GCODE_END`, ensuring that float type variables are included in this definition. For example: Considering that the variables `XOFF`, `YOFF` and `ZOFF` are calculated as 12.85, 11.25 and 10.50 respectively. `PRB_GCODE_END` should occur as follows: `G92 X-12.85 Y 11.25 Z10.50 \n`

# Answer
> 3 votes
You can't. Variables and macros are completely different concepts and handled by completely different parts of the compiler toolchain.

Instead you will need to build your string up into a char array (or whatever format the `_user_gcode_exec()` function accepts) with the likes of sprintf.

---
Tags: c++
---


# Question
Title: Unsure if my NEMA 14 stepper motor wiring is correct
So I'm pretty brand new to Arduino's in general so I do apologize if its a simple mistake. But basically I'm trying to use the \<Stepper.h\> library to control my NEMA 14 motor on an arduino with a CNC shield and a A4988 driver. Specifically at this moment I am testing out this code:

```
/*
 Stepper Motor Control - one step at a time

 This program drives a unipolar or bipolar stepper motor.
 The motor is attached to digital pins 8 - 11 of the Arduino.

 The motor will step one step at a time, very slowly.  You can use this to
 test that you've got the four wires of your stepper wired to the correct
 pins. If wired correctly, all steps should be in the same direction.

 Use this also to count the number of steps per revolution of your motor,
 if you don't know it.  Then plug that number into the oneRevolution
 example to see if you got it right.

 Created 30 Nov. 2009
 by Tom Igoe

 */

#include <Stepper.h>

const int stepsPerRevolution = 200;  // change this to fit the number of steps per revolution
// for your motor

// initialize the stepper library on pins 8 through 11:
Stepper myStepper(stepsPerRevolution, 8, 9, 10, 11);

int stepCount = 0;         // number of steps the motor has taken

void setup() {
  // initialize the serial port:
  Serial.begin(9600);
}

void loop() {
  // step one step:
  myStepper.step(1);
  Serial.print("steps:");
  Serial.println(stepCount);
  stepCount++;
  delay(500);
}

```

Now unfortunately when I run this code I can hear the motor whirring, but it doesn't revolve. I'm guessing that either I wired the motor incorrectly, or because I'm using a CNC shield the pins in the code should be different. Also, I've checked the voltage going into the driver in accordance with this website. I've also attached pictures below of my setup to just to make everything clear:

1. Picture of CNC shield atop Arduino board with wires connected as follows:
2. Picture of Stepper motor I'm using:
3. Specifications of the NEMA 14 motor I'm using: Can be seen here

I'm sorry for the convoluted post but I am kind've stuck so any help would be greatly appreciated and if there's any more info needed to help clarify my problem I will update the post or reply to your comments. Thanks!

# Answer
> 1 votes
I would first check with a multimeter which pins from the the shield have voltage. Draw on a piece of paper the sequence of pin activated by the driver and check your motor connection. Probably you have just inverted two wires, this would also explain the whirring sound.

---
Tags: stepper-motor
---


# Question
Title: avrdude fuse error when programming ATMEGA328 without crystal
I built several boards with an ATMEGA328 and no crystal a couple of years ago. I programmed them successfully with a bootloader using usbasp, and with a sketch using the Arduino serial interface. I have now made some more, but I get an error message from AVRDUDE when I try to burn the bootloader:

> \***failed;
> avrdude: WARNING: invalid value for unused bits in fuse "efuse", should be set to 1 according to datasheet This behaviour is deprecated and will result in an error in future version You probably want to use 0xfd instead of 0x05 (double check with your datasheet first).

I followed the instructions here and I am using the hardware configuration archive referenced on that page: breadboard-1-6-x.zip.

If I reprogram the bootloader on a device that does have a crystal, it works if I select Arduino Pro/Pro Mini (3.3V, 8MHz), but fails with the message above if I select the breadboard specified in the boards.txt from breadboard-1-6-x.zip.

There are no other error messages, but... if I turn on verbose, it works.. turn verbose off and it stops working again. Maybe verbose mode modifies the timing enough to make it work.

I know that you can use the -B option to slow down avrdude when you run it from the command line: is there a way of doing the same thing from within the Arduino environment?

# Answer
> 4 votes
The ATMega328P datasheet has the following table in it:

The top 5 bits of the of the Extended Fuse Byte are default `1` and are reserved. You're not really supposed to change them, since they might be used in the future for a 328P-like part and setting them to something other than `1` could have unexpected results. In the 328PB variant bit number 3 **is used** for "Disable Clock Failure Detection".

The lower three bits of 0xFD and 0x05 are both 0b101. In other words, taking into account only the bits you should be setting, for the BODLEVELn fuses, they would have the same effect. But you are being WARNED that you should be using 0xFD rather than 0x05 for the above reason.

The boards.txt that comes in the breadboard-1-6-x.zip has a line that looks like this:

> atmega328bb.bootloader.extended\_fuses=0x05

You *could* change this yourself by editing the file, but really for what you're doing I'd recommend MCUdude MiniCore which is comparatively up to date. If nothing else, its boards.txt file has been written with the correct fuse values. You can see there for a plain 328P (not PB) which does not support clock failure detection, the CFD bit is just hardcoded to 1 in the file.

The message you're seeing is a "WARNING" through, rather than "ERROR". The distinction being that warnings don't actually stop you from continuing. It is likely that if you're having a problem isn't not really because they've incorrectly specified the high-order bits of the fuse. If it's halting, it may be arduino-builder see a non-zero exit code for avrdude and thinking this means "ERROR" rather than "WARNING", in which case this problem will go away if you edit the boards.txt file (or adopt MiniCore) such that no longer produces the warning.

Unless you've brought the effective system clock below 1MHz, probably lower still, it's not likely that you'll need to change from the default ISP clock rate. If you do though, that can also be done by editing board package files.

---
Tags: atmega328, bootloader, avrdude
---


title: Arduino freezing frequently

text:
# Question
Title: Arduino freezing frequently
I'm using an Arduino Nano for programing an automatic hand sanitizer that has a thermometer. But after running for some time the board freezes and only restarting can solve the issue. While checking the serial monitor it suddenly stops working.

The program includes reading distance from an ultrasonic sensor and temperature from an IR thermometer (distance and ambient temperature are read continuously and the serial monitor will constantly display values). At random when the temperature is read and is displayed on the OLED screen, the board freezes (board freezes only at this time) and restarting can make it work 1 more time and then freezes again.

Question 1 Is it something to do with the code or is it a hardware issue?

Question 2 Does a clone version of NANO cause such problem? (I'm using a clone version)

This is my code:

```
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();
Adafruit_SSD1306 display(-1);
//Adafruit_SSD1306 display(128, 64, &Wire, -1);

#define trigPin 12 // Trigger pin
#define echoPin 11 // echo pin

float roomTemp; // ambient temperature
float objectTemp, stemp; // object temperature

int readcount = 0;
float threshold= 3.5 ;

int maximumRange = 15; // Maximum range needed
int minimumRange = 3; // Minimum range needed
long duration, distance; // Duration used to calculate distance
int dtime;
unsigned long rememTime;

// motor coding
int set_time;
float distance_cm;
unsigned long ultra_time;
int set_cm = 20;
int motor = 2; // Output for Motor drive
int flag = 0;

void setup() {
  Serial.begin(9600);// initialize serial communication at 9600 bits per second:

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

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C) ;
  delay(200);
  display.clearDisplay();
  display.setTextColor(WHITE);
}

void loop() {
  // temperature sensor coding
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  duration = pulseIn(echoPin, HIGH);
  //Calculate the distance (in cm) based on the speed of sound.
  distance= duration * 0.034/2;

  // reading object and ambient  temperature
  objectTemp = threshold + mlx.readObjectTempC() ;
  roomTemp = mlx.readAmbientTempC() ;

  // print to Serial port
  Serial.println("Object:" + String(objectTemp) + ", Ambient:" + String(roomTemp));
  Serial.println(distance);

  // display on OLED
  display.clearDisplay();
  display.setTextSize(1);
  display.setCursor(0, 25);
  display.print("Dis:" + String(distance) + "cm");
  display.setCursor(65, 25);
  display.print("Room:" + String(roomTemp).substring(0, 4) + "C");
  display.display();
  display.setTextSize(2);
  display.setCursor(0, 0);

  if (distance < minimumRange) {
    display.print("TOO CLOSE!");
  }
  if ((distance >= minimumRange) && (distance <= maximumRange)) {
    if (readcount == 5) { // after reading 5 consecutive time
      disptemp();
    } else {
      display.print("HOLD ON"); // when in range, ask user to hold position
      stemp = stemp + objectTemp;
      readcount++; // until approx. 5 x 200 ms = 1 sec
    }
  } else { // if user is out of range, reset calculation
    dtime = 100;
    readcount = 0;
    stemp = 0;
  }
  display.display();
  delay(dtime);
  Serial.println("count  :"+String(readcount));
}

void disptemp() {
  objectTemp = stemp / 5; // get the average reading of temp
  display.setTextSize(1);
  display.print("YOUR TEMP:");
  display.setTextSize(2);
  display.setCursor(60,5);
  display.print(String(objectTemp).substring(0, 4) + "C");
  display.display();
  readcount = 0;
  stemp = 0;
  if (objectTemp >= 38) {
    play_alert();
  } else {
    play_ok();
  }
  ultrasonicRead();
  dtime = 5000; // wait for 5 seconds
}

void play_ok() {  // play three sequential notes when object temperature is below 37.5C
  tone(3, 600, 1000);  // pin,frequency,duration
  delay(200);
  tone(3, 750, 500);
  delay(100);
  tone(3, 1000, 500);
  delay(200);
  noTone(3);
}

void play_alert() { // beep 3x when object temperature is >= 37.5C
  tone(3, 2000, 1000);
  delay(1000);
  tone(3, 3000, 1000);
  delay(1000);
  tone(3, 4000, 1000);
  delay(1000);
  noTone(3);
}

void ultrasonicRead() {
  if (distance < set_cm) {
    digitalWrite(motor, HIGH);
    Serial.println("Motor On");
    delay(500);
    digitalWrite(motor, LOW);
    Serial.println("motor off");
  }
}

```

# Answer
> 4 votes
Any allocation / de- or re-allocation of memory\[1\] during run time, will cause the heap (the pool of memory from which those allocations are made) to expand until the heap and the stack grow toward each other enough to collide, at which point one overwrites part of the other with unpredictable results.

Strings are allocated from the heap. Strings that are built up little by little, as with:
`Serial.println("Object:" + String(objectTemp) + ", Ambient:" + String(roomTemp));`
cause allocation several allocation / de-allocations.

As a simple-to-implement test, comment out the statements that use the String object and just print the raw data. Your program should run without crashes.

To recreate what you're now doing with Strings, I'd suggest using `snprintf()` to build up your output into a fixed-size output buffer, which can be a local character array (allocated on the stack and de-allocated when the containing function exits). This should be equally stable as the abbreviated experiment I proposed above.

\[1\] \*Unless allocated memory is de-allocated most-recent-first. And even that assumes foreknowledge of the memory allocation algorithm in use, and so, is non-portable).

One way around this is to write one's own memory allocator/de-allocator, which has a pre-assigned pool of fixed-length blocks, one of which it supplies for *any* memory request of any size, so long as:

1. there is a free block to allocate; and
2. the requested size can fit in (the data-space of) a pre-assigned block.

# Answer
> 1 votes
In addition to some of the above comments;

Your Nano may not support the watchdog. Please check This post on the Arduino forum

If you are looking for "There are many small programs..." I'll just post the functions I use for getting free memory, heap and stack information below.

```
int freeRam()
{
    extern int __heap_start, *__brkval;
    int v;
    return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
}

uint8_t * stack()
{
  uint8_t * ptr;
  ptr = (uint8_t *)malloc(4);
  free(ptr);
  return ((uint8_t *)(SP));
}

uint8_t * heap()
{
       uint8_t * ptr;
       ptr = (uint8_t *)malloc(4);
       free(ptr);
       return(ptr);
}

```

---
Tags: arduino-nano, error
---


# Question
Title: Host a webserver on an ESP32D that has a hyperlink that triggers an Arduino song through a buzzer
I would like to use my ESP32D to create a wireless access point and host an HTML page that has a hyperlink and a few other things on it that triggers an Arduino song (rickroll), and plays it through a buzzer.

I just need to know how to host the webserver and make the trigger hyperlink work, right now the HTML is set to send "trigger" whenever the link is pressed.

HTML file: https://pastebin.com/sGmPPVYG

Arduino-song: https://github.com/robsoncouto/arduino-songs/blob/master/nevergonnagiveyouup/nevergonnagiveyouup.ino

# Answer
This is a partial answer. I assume you already know how to build a Web server on you ESP32, and how to react to client requests. If not, there are tutorials available on the Internet. Here I will specifically discuss the issue of the hyperlink.

You wrote:

```
<a href="trigger">Click Here To Trigger The Rick Roll!/a>

```

Not only the closing tag is incorrect (it should be `</a>`), but such a link is likely not what you want. The semantics of an hyperlink is “go fetch that resource and display it here, replacing the current page”. Unless you do have a displayable resource (Web page, image...) on your server actually named “trigger”, you do not want an hyperlink. You want a clickable item that may look like an hyperlink and, when clicked, triggers a request to the server, but without replacing the current page.

So I would start by replacing the link by a generic container:

```
<div id="trigger">Click Here To Trigger The Rick Roll!</div>

```

Then, style it like a link. I don't quite like the underlining, but you can add it if you wish:

```
#trigger {
  color: blue;
  cursor: pointer;
}

```

Then, within a `<script>` tag, add the desired behavior:

```
window.onload = () => {
    document.getElementById("trigger").onclick = () => {
        fetch("trigger", { method: "POST" });
    };
};

```

When the user clicks on the element, the client will send a “POST” request to the server for the “trigger” resource, and the server can react to this by playing the song. You could use a “GET” request instead, but that would violate the semantics of “GET”, which is to retrieve a resource from the server, without affecting its state.
> 1 votes

---
Tags: esp32, web-server, sound
---


# Question
Title: Resistor - Correct value for optocoupler, but dont have that size
I am making a shutter for my camera using a Arduino and an optocoupler.

I understand most of most parts, but unsure about the resistor because I don't have the correct size. 5V will be coming from the Arduino, and the 4N35 will need 1.3V 10mA. This leads to a 380Ω resistor.

Now I only have 100Ω, 220Ω, 330Ω, and 1kΩ resistors. I have read I shouldn't use anything lower than 380Ω and only use higher but 1kΩ seem a little too high haha.

Just looking for some pointers please.

# Answer
1kΩ will be just fine. But if you want lower you could take two 1kΩ and place them in parallel - that will give you 500Ω.

BTW - 1kΩ will give you ((5-1.3)/1000=) 3.7mA through the diode of the optocoupler, and 500Ω will give you ((5-1.3)/500=) 7.4mA.
> 1 votes

# Answer
And 330 will give you just over 11mA, I'd go with that
> 1 votes

---
Tags: resistor, opto-isolator
---


# Question
Title: Voltage from batteries in series operating on 3 ATTiny, 3 Buttons, and 3 Piezo buzzers
I intend to power three ATTiny45 chips (each requiring around 3.5V) in parallel with 2 pill batteries (namely Maxwell's **CR2032**) in series (which would come to around 6V). They will each play a sound with a piezo buzzer when a button is pressed.

Now maybe my thinking is wrong but I think dividing the power between the three chips may result in only around 2V delivered to each chip? Does the other components play a role?

So my question is this:

* How much voltage is delivered across elements in parallel?
* What changes should I do to the wiring to make the most of the voltage?
* What kind of resources should I get to make sense of what to do? Cause I thought I was more advanced but this stomped me.

In any case I've added the schematic of what's intended.

*\[This schematic used to contain resistors to pull the switch but this need was removed with the help of jsotola's `input_pullup` comment\]*

simulate this circuit – Schematic created using CircuitLab

# Answer
> 1 votes
If you connect the AtTiny chips in parallel, they will all receive the full voltage from your battery. If you exceed the current output of your battery the voltage will droop.

If the AtTiny chips need 3.5V and you give them 6V instead, it will likely destroy the chips.

The short answer: Don't try to drive microcontrollers directly from batteries. You should get a 3.5V switching power supply. Then you will be able to drive all 3 chips cleanly from your battery. (Switching power supplies are very efficient. They don't waste much power at all.)

Note that button cells produce very small total power (in milliwatt/hours) so they won't drive your processors for very long before they are exhausted. I suggest using 4 AA batteries and a switching regulator instead. The 4 AA batteries would give you a 6V VIN to your voltage regulator, but a lot more total power.

---
Tags: attiny, battery, wires
---


# Question
Title: I2C communication between Arduino Uno and Nodemcu32-s (ESP32)
I want to send data between an ESP-32 (NODEMCU-32S) and an Arduino Uno but I haven't found any source on how to do that, so I tried this code:

ESP-32 code:

```
#include <Wire.h>

void setup() {
  Serial.begin(9600);
  Wire.begin(21, 22);      /* join i2c bus with SDA=D1 and SCL=D2 of NodeMCU */
}

void loop() {
  Wire.beginTransmission(8);
  Wire.write(3);  /* sends hello string */
  Wire.endTransmission();  /* stop transmitting */
  Wire.requestFrom(8, 18); /* request & read data of size 13 from slave */
  while (Wire.available()) {
    char c = Wire.read();
    Serial.print(c);
  }
}

```

And Arduino code:

```
#include <Wire.h>

void setup() {
  Wire.begin(8);                /* join i2c bus with address 8 */
  Wire.onReceive(receiveEvent); /* register receive event */
  Wire.onRequest(requestEvent); /* register request event */
  Serial.begin(9600);           /* start serial for debug */
}

void loop() {
  delay(100);
}

// function that executes whenever data is received from master
void receiveEvent(int howMany) {
  while (0 < Wire.available()) {
    int c = Wire.read();        /* receive byte as a character */
    Serial.print(c);            /* print the character */
  }
}

// function that executes whenever data is requested from master
void requestEvent() {
  Wire.write("hello esp");
}

```

But I found that no data was sent.

I connected pin 21 to A4 and 22 to A5 directly.

I cannot find where the problem is. Also, I don't know whether the device address is correct or not, since when I tried an I2C scanner it didn't discover any device.

Also, I hope that there is a similar method to have two-way UART communication between the Arduino and ESP as I found none since I need both chips to send data to each other.

# Answer
I'm working on something similar at the moment. Not a complete answer put some thoughts:

* Have you considered that the Uno is a 5v board and the ESP32 is 3.3v? You may need a signal level shifter (there are many to chose from) something like Pololu-2595 which is breadboard friendly.
* There's a good ESP32 I2C explanation at Random Nerd Tutorials.
> 1 votes

---
Tags: arduino-uno, i2c, esp32, uart, wire-library
---


# Question
Title: How do I use I2C from an Arduino Uno when I have a GSM shield mounted?
This may be an extremely obvious question but I don't seem able to find a definitive answer.

I have an Arduino Uno and a Sim900 GPRS/GSM shield fitted on top of it. I had I2C working on the Arduino to communicate with a Raspberry Pi, but now that I have put the shield on top I can't get the Pi to detect the Arduino. As far as I can tell the SDA and SCL pins on the Arduino aren't being used by the shield so does anyone have any idea how I go about this?

Thanks

# Answer
There seems to be a number of different Sim900 shields from different suppliers? I suggest you check/post the datasheet of the one you're using. If I2C works without the shield, and does not work with the shield connected , then it seems logical that there is a pin clash.

There is a good Random Nerd Tutorial on getting started with the shield on a Uno. Maybe test it out completely before connecting to the Raspberry Pi?

The Raspberry Pi is 3.3v and the Uno is 5v. You didn't mention level shifting in your question, but it may be worthwhile.
> 1 votes

---
Tags: arduino-uno, shields, gsm, i2c, communication
---


# Question
Title: Creating a sine wave with a DAC and feeding it back
I want to produce a digital sine wave, send it to DAC0, and then receive it back as input on A0 and plot the graph. I am using an Arduino Due. I wrote the following code:

```
#define maxSamplesNum 120
#define Sample 50000000/maxSamplesNum  // sample for the 50Hz signal expressed in microseconds

static int Table[maxSamplesNum] =                        // lookup table  for sine wave table
  {
    0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1,
    0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4,
    0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc,
    0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f,
    0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a,
    0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a,
    0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d,
    0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a,
    0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2,
    0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf,
    0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4,
    0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794
  };

int i = 0;
int sample;
int sensorPin = A0;
int sensorValue = 0;

void setup() {
  Serial.begin(9600);
  analogWriteResolution(12); // set the analog output resolution to 12 bit (4096 levels)
  analogReadResolution(12); // set the analog input resolution to 12 bit
}

void loop() {
  sample = 50;

  analogWrite(DAC0, Table[i]); // write the selected waveform on DAC0

  i++;
  if (i == maxSamplesNum)  // Reset the counter to repeat the wave
    i = 0;
  delayMicroseconds(sample); // Hold the sample value for the sample time
  sensorValue = analogRead(sensorPin);
}

```

I want to create a 3.3 V (P-P) sine wave but I don't how to set the amplitude in this wave.

Also I would like to redirect the sine wave output from DAC0 to the A0 Pin and plot the graph to check if generating the sine wave was successful. How do I plot the graph ?

I uploaded the program but there was no result. I tried to read data from A0, but there wasn't any output. What am I doing wrong?

# Answer
I ran your code unmodified and plugged in an oscilloscope to look at DAC0 (looks an OK sine wave) and A0 (looks flatline). Hope this helps.
> 0 votes

---
Tags: arduino-due, adc, input, dac
---


title: Adding zero padding to decimal values

text:
# Question
Title: Adding zero padding to decimal values
I want to add zero before the float number like this:

```
010.0

```

The code I'm using is this:

```
if(value < 10){
  lcd.print(F("0"));
}

lcd.print(value);

```

But when the value is exactly 10, it adds the zero anyway:

```
0010.0

```

I tried something like this but haven't had any luck:

```
if(value < 10 && value != 10){
  lcd.print(F("0"));
}

```
* How can I solve this issue?

**\- EDIT:**

```
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3B, 16, 2);

#define turnOff 3
#define turnOn 2
#define gateStatus 8
#define btn 4

float ADC0, current, ADC1, voltage, ADC2, temp, watt;
int8_t state, btnState, btnPushed, btnToggle, lcdClear;
uint32_t deBounce = 0;

void setup() {
  analogReference(EXTERNAL);
  pinMode(turnOff, OUTPUT);
  pinMode(turnOn, OUTPUT);
  pinMode(gateStatus, INPUT);
  pinMode(btn, INPUT_PULLUP);
  pinMode(13, OUTPUT);
  lcd.begin();
}

void loop() {
  digitalWrite(13, LOW);
  state = digitalRead(gateStatus);
  btnState = digitalRead(btn);

  if (!btnState) {
    if (millis() - deBounce > 200) {
      btnPushed = 1;
      deBounce = millis();
    }
  }
  if (btnPushed && btnState) {
    btnToggle = 1;
  }
  if (btnToggle && state) {
    digitalWrite(turnOn, HIGH);
    delay(5);
    digitalWrite(turnOn, LOW);
    btnToggle = 0;
    btnPushed = 0;
  }
  if (btnToggle && !state) {
    digitalWrite(turnOff, HIGH);
    delay(5);
    digitalWrite(turnOff, LOW);
    btnToggle = 0;
    btnPushed = 0;
  }

  for (int i = 0; i < 500; ++i) {
    ADC0 += analogRead(A0);
  }
  ADC0 /= 500;
  current = ADC0 * (2.5 / 1023.0);
  current = current / 0.211;

  for (int i = 0; i < 500; ++i) {
    ADC1 += analogRead(A1);
  }
  ADC1 /= 500;
  voltage = ADC1 * (2.5 / 1023.0);
  voltage = voltage * 20.2;

  for (int i = 0; i < 100; ++i) {
    ADC2 += analogRead(A2);
  }
  ADC2 /= 100;
  temp = ADC2 * (2.5 / 1023.0);
  temp = temp * 100.5;

  watt = voltage * current;

  lcd.setCursor(0, 0);
  if(voltage < 10){
    lcd.print(F("0"));
  }
  lcd.print(voltage);
  lcd.setCursor(5, 0);
  lcd.print(F(" V"));

  lcd.setCursor(9, 0);
  if(temp < 10){
    lcd.print(F("0"));
  }
  lcd.print(temp, 1);
  lcd.print((char)223);
  lcd.print(F(" C"));

  if (state) {
    lcd.setCursor(0, 1);
    lcd.print(F("   OUTPUT OFF   "));
    lcdClear = 1;
  }

  else {
    if (lcdClear) {
      lcd.clear();
      lcdClear = 0;
    }
    lcd.setCursor(0, 1);
    if (current < 10) {
      lcd.print(F("0"));
    }
    lcd.print(current);
    lcd.setCursor(5, 1);
    lcd.print(F(" A"));

    lcd.setCursor(9, 1);
    if (watt < 10) {
      lcd.print(F("0"));
    }
    if (watt < 100) {
      lcd.print(F("0"));
    }
    lcd.print(watt, 1);
    lcd.setCursor(14, 1);
    lcd.print(F(" W"));
  }
}

```

# Answer
This looks like a rounding problem. If the number you want to print lies within the open interval (9.95, 10), the condition `value < 10` is true, as the number is strictly less than 10. Obviously, `value != 10` is also true. Yet, `lcd.print(x, 1)` will round the number to the closest multiple of 0.1, which in this case is 10.

I see no better solution than handling the rounding yourself. I would use integers for the comparison, as they avoid all rounding issues:

```
// Print a float to the LCD in 2.1 format (xx.x), left padded with a
// zero if needed. Assume x < 100.
void printPadded(float x)
{
    // Left pad.
    int i = round(x * 10);
    if (i < 100) lcd.write('0');

    // Print the rounded value.
    lcd.print(i * 0.1, 1);
}

```
> 2 votes

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


# Question
Title: Valid options for output port on Mega 2560
I would like to adopt this library on an Arduino Mega2560:

https://github.com/gueei/DShot-Arduino

However, the macro `DSHOT_PORT` needs defined for the Mega2560 here: https://github.com/gueei/DShot-Arduino/blob/master/src/DShot.h

So I need to add a `#if defined(__AVR_ATmega2560__)` macro to that `DShot.h` header, however, it is not clear to me where to lookup the port mapping on a 2560 mega. I'm looking directly at the schematic itself here: https://www.arduino.cc/en/uploads/Main/arduino-mega2560-schematic.pdf

And understand that the 'ports' are groupings of IO where the pins are described as `P?#`, ? being the port letter and # being 0-7.

So what are my valid options? It appears that some ports (A,C,L) aren't pinned at all, some (D,J) only a few pins, and just about none of them (except K/F) have all port pins utilized. Also, I can see most of these pins are reserved for some type of functionality (analog, SPI, etc). I'm assuming I'm looking for a port with available pins reserved for PWM, such as Port B (pins 10-13 are PWM). Would this be correct?

# Answer
> 1 votes
It would seem this library needs a single pin to communicate. So it doesn't really matter whether the port you choose has only a few pins available. Also, you do not care that some pins can have extra functionality, like SPI, I2C, etc, unless you do plan to use that functionality.

There is one think you should be aware of: the library uses the `in` and `out` assembly instructions to access the port. These instructions can only access the ports that are mapped in the regular I/O space of the microcontroller, not those that are in the “extended I/O” space. In the case of the ATmega2560, this means you can use any of the ports A through G, but you cannot use H, J, K nor L.

---
Tags: arduino-mega, port-mapping
---


# Question
Title: IDE compiles incorrect file after renaming them
I am using the stand alone Arduino IDE to build some projects, and I have a few `.cpp` files now, but during work I renamed them `.c` and back. When compiling the project now (with `Ctrl`-`R`), it is still trying to compile the `.c` files. But, I don't even see them on disk!

Changing the `.cpp` makes no difference. I am used to IDEs having some kind of project file, or a "clean project" option, but I cannot find those here.

# Answer
> 0 votes
The Arduino IDE does not monitor changes to open files. So if you rename or change a file externally (i.e. in another editor), the IDE won't update the file contents. Therefore, after such a change, a restart might be necessary.

Note: If you use another editor to change a file but only compile (and upload) in the IDE, this will work, because the compiler correctly reads the updated file. But editing the source in the IDE and an external editor at the same time might overwrite either change!

---
Tags: arduino-ide
---


# Question
Title: Will the L9823 work at 3.3 V with Wemos boards?
Or is it 5 V only?

https://www.st.com/en/automotive-analog-and-power/l9823.html

I see in the data sheet it says under Absolute Maximum:

> Supply Voltage: VDD -0.3 V to 7 V

Then, under Electrical Characteristics:

> 4.5 V \< VDD \< 5.5 V; unless otherwise specified.

Is the Electrical Characteristics section just listing values for an example voltage of 5 V, or does the chip need 5 V to work properly?

# Answer
No. The undervoltage puts it in reset at 3.95V per the ST data sheet. It is a 5v only part with a wide tolerance on VCC. It was designed many years ago as an automotive part. It is a very nice part and performs well.
> 1 votes

# Answer
The *Absolute Maximum* section in a datasheet describes what will damage a component, or shorten its life span; it does not state the acceptable range of values that will make the component work as expected. It is not a design guideline.

You can deduce from these Absolute Maximum data that a Vdd of 3.3 V will not damage the IC, but not that it will work well at that voltage.

In this case, the datasheet says that all Electrical Characteristics *are specified at* a Vdd of about 5 V. This by itself does not necessarily mean the IC won't work at lower voltages, but it is a hint.

But, further on in the Electrical Characteristics, it is stated that the IC could reset at any Vdd between 2.5 V and 3.95 V, so the IC will very probably not work reliably at 3.3V.
> 1 votes

---
Tags: esp8266, voltage
---


title: Timing push button code

text:
# Question
Title: Timing push button code
I am trying to time how long button is held for. The code seems to work but with two problems:

1. the millis values are being read wrongly. If you hold the button for 1 second, it returns holdTime of about 3000 ms. A quick click returns holdTime of about 1000 ms.
2. Each successive button press adds to the previous millis value so holdTime just gets higher and higher and doesn't measure how long the button has just been pressed for

Any ideas or advice for newbie welcome!

```
#include <LiquidCrystal.h>

const int button1Pin = 1;  // pushbutton 1 pin
const int ledPin = 13;     // LED pin

int button1State, button2State;  // variables to hold the pushbutton states
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int startPressed = 0;
int endPressed = 0;
int holdTime = 0;

void setup() {
  // Set up the pushbutton pins to be an input:
  pinMode(button1Pin, INPUT);

  // Set up the LED pin to be an output:
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);
\
}

void loop() {

  while (digitalRead(button1Pin) == LOW) {}

  button1State = digitalRead(button1Pin);
  startPressed = 0;
  endPressed =0;
  holdTime = 0;

  // if button1 or button 2 are pressed (but not both)
  if (button1State == LOW) {
    digitalWrite(ledPin, LOW);   // turn the LED on
    startPressed = millis();
  } else {
    digitalWrite(ledPin, HIGH);  // turn the LED off
    endPressed = millis();
    holdTime = endPressed - startPressed;
  }
  lcd.print("You pressed for");
  lcd.setCursor(0, 1);
  lcd.print(holdTime);
  lcd.print("ms");
  while (digitalRead(button1Pin) == LOW) {}
  lcd.clear();
  startPressed =0;
  endPressed =0;
  holdTime = 0;
}

```

# Answer
> 1 votes
Your source has several flaws, and one error that generates the output you see. This is the analysis of the error.

In `loop()` you start by waiting for the button pin to get HIGH, following by another read of the pin's state that will most probably return the same, HIGH. *Note: Only if your button bounces with just the right timing, this last read will return LOW.*

```
while (digitalRead(button1Pin) == LOW) {}
button1State = digitalRead(button1Pin);

```

Next you check the pin's state, and let's assume that it is HIGH. Only the `else` part is executed, and it calculates the `holdtime` as the difference of `endPressed` and `startPressed`. The former has the current value of `millis()`, but the latter is 0 as you initialized it.

That's why you're getting always growing values.

**How to solve?**

Think about the `while` loops, do you need them? Remember that `loop()` is already called repeatedly.

You may need a state variable that stores the last pin's state, so you can detect changes.

---
Tags: button, millis
---


title: ArduinoJSON define as extern

text:
# Question
Title: ArduinoJSON define as extern
My sketch contains 2 `.h` files. one defines

on 1st `.h` file:

```
#define JSON_SIZE_IOT 400
#define JSON_SIZE_SKETCH 300
StaticJsonDocument<JSON_SIZE_IOT> paramJSON;
StaticJsonDocument<JSON_SIZE_SKETCH> sketchJSON;

```

and other need to define `paramJSON` and `sketchJSON` as `extern`

on 2nd `.h` file:

```
extern JsonDocument paramJSON;
extern JsonDocument paramJSON;

```

but I get this error:

```
error: conflicting declaration 'ArduinoJson6172_91::StaticJsonDocument<400u> paramJSON'
 StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

```

....

```
: previous declaration as 'ArduinoJson6172_91::JsonDocument paramJSON'
 extern JsonDocument paramJSON;

```

# Answer
For an `extern` the whole definition has to match the "master" definition.

So if you have:

```
StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

```

then you `extern` has to be:

```
extern StaticJsonDocument<JSON_SIZE_IOT> paramJSON;

```

Of course you have to make sure your `JSON_SIZE_IOT` is the same for both - so it's best if that comes from a common source.

This is known as *explicit instantiation declaration* and you can read more about it in the Class template C++ reference.
> 1 votes

---
Tags: json
---


# Question
Title: Problems with green TWI (I2C) port on Arduino Braccio Shield
Summary: The green TWI/I2C port on my Braccio shield I2C port hasn't worked for me so far. Looking for advice or information please.

Detail: I'm using the Arduino (Tinkerkit) Braccio robot arm for self education. It comes with a Uno based Braccio Shield. Tinkerkit no longer seems to be in business and documentation is a bit scarce. The shield uses KF2510 style connectors for servos (orange), inputs (white), serial (yellow) and importantly for my question a TWI/I2C port (green).

The green four pin TWI/I2C connector provides GND, +5V, SDA (A4), SCL (A5). However the SDA and SCL connections are reported to not be direct, but that "a very tiny chip (located next to the I4 connector) buffers between the green connector and the Arduino pins SDA and SCL" . A photo of the chip described is below.

Contrary to the reports of a "buffer" studying the schematic shows a level shifter PCA9306TI and two sets of 10K pullup resistors (R7,R8 and R11,R12) on the bus on both sides of the chip. VREF2 on the outboard side of the chip has a R9 220K resistor to +5V.

The other side of my I2C connection was an Arduino Pro-mini 5V. I was never able to get it working using the green port described, but it works fine directly hooked into SCL and SDA bypassing the level shifter.

My questions (sorry for the long lead up) are:

1. Has the green TWI port been level shifted to expect ~3V? (Only really came to this conclusion writing this all up clearly).
2. If I want to change the green TWI port to 5V I2C can I replace R9 220K with a zero ohm jumper?
3. The 10K pullups (R7,R8 and R11,R12) seem larger than anticipated (I had anticipated about 4.7K for 5v or about 2.4 for 3V)? Can they be removed and left open if I have a single set of pullups elsewhere on the bus? Or better suggestions?

Thanks!

**Update 2021/01/30**

Well my I2C debugging skills are improving researching this! As a test bed I set up a clean working I2C bus with two MCU's running the Arduino Example Master/Writer Slave/Receiver sketches by Nicholas Zambetti. I tested the I2C signal on the oscilloscope to make sure it was clean. All good. To that test bed I connected the Braccio shield (5V, GND, SCL, SDA). Connecting the Braccio shield changes the I2C signal in interesting ways, with partial strength (runt) pulses, and round shoulder slow rises. Connecting via the green TWI port seems to accentuate the runt pulse aspect. Also interesting the oscillscope was still able to decode the signal. Still working on figuring this out.

Pic 1. First test - SCA and SCL connected via pin headers in top left of shield picture above.
Pic 2. Second test - SCA and SCL connected via green TWI port  Pic 3. Clean Signal (no Braccio Shield connection)

# Answer
I fear we have a colloring issue. Your green is my blue ;-).

I have looked into the data sheet of the level shifter IC and TI only describes scenarios with a higher voltage on the right side and a lower voltage on the left side. Also the allowed voltage translations do not contain 5V to 5V. So I would say in equal voltage scenario the Level shifter may not work.

Answers

* Q1: The TWI port is always used with 5V (not ~3V). The Arduino that is supposed to use the shield might be a 3.6V version (like a DUE or M0). Perhaps the TWI port is only intended for this use case: A low voltage arduino with a 5V device. I admit: This should be noted in the documentation. So perhaps Braccio shields work outside the specification and may works under normal circumstances. But meanwhile I begin to understand why they are out of busines ;-).
* Supplement: the SCL and SCL signals are routed to two pairs of header pins as they are connected to different pins on different Arduinos. On a UNO you can not use A4 and A5 for analog as they are used for I2C for example. Do you use A4 A5 in any way? Or did you connect the second I2C pin pair in the power header when you had used the TWI connector? (rhetoric question ;-) of cause I will change the answer if you give me more information ;-) )
* Q2: The 220k resistor is necessary as it limits the current through the chip if VRef1 is lower than VRef2. Removing it with 0 Ohms would be a bad idea. As long as 5V is used on both sides, nothing would happen. But if Vref1 is 3.6Volts, you would waste energy and perhaps the chip would take part at a grill fest.
* Q3: Most I2C devices breakout boards already use their own pullup resistors. So lowering the pullups is not the best idea. -\> too high current with LOW signals as the devices pull ups and the braccio pull ups are set in parallel. -- There is a chance, that the resistors are too large for devices that don't use their own pull ups, but at a 100kHz bus speed I don't think, this could cause an issue.

BTW: You do not need to exchange the pull ups, if you insist to try out different values. Just use parallel resistors to lower the resistance (10K || 10K -\> 5K) \[|| means connected in parallel\] (R || Rp -\> (R\*Rp) / (R+Rp))
> 2 votes

---
Tags: arduino-uno, i2c, shields
---


# Question
Title: Code is not running, servo does not even spin
I am trying to run a program which works as follows:

An LDR is integrated in a box. A block is placed on top. This box can be rotated by a servo. The program is supposed to make the box turn until the block slides and lifts off from the LDR.

At that point the servo angle is stored and used to calculate the friction coefficient.

Finally, the answer to this calculation is printed on an LCD and the program repeats by first returning the box to the original state. The entire programs runs on an Arduino and an Arduino Lotus. Why doesn't the servo rotate?

```
//servo
#include <Servo.h>

Servo myservo;
int previous_angle = 0;
int angle = 0;

//lightsensor
int lightsensor = 0;
int LIGHT = 800;
int DARK = 940;

//LED screen
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

void setup() {
  Serial.begin(9600);
  myservo.attach(6);

  pinMode(lightsensor, INPUT);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  delay(100);
}

void loop() {
  int i = previous_angle;
  int lightStatus = analogRead(lightsensor);

  if (lightStatus >= DARK) {
    delay(300);

    while (int i = previous_angle) {
      i<=90;
      i = i+1;
      myservo.write(i);
      delay(45);
    };
  } else if (lightStatus < DARK) {
    for (int i = previous_angle; i>0;) {
      delay(300);
      int angle = tan(i);
      display.clearDisplay();
      display.setTextSize(1.5);
      display.setTextColor(WHITE);
      display.setCursor(0,0);
      display.println(angle);
      display.display();
      delay(300);

      myservo.write(0);
      delay(45);
    };
  }
}

```

# Answer
> 2 votes
For starters: this bit is a strange mixture of `for` and `while` syntax:

```
while (int i = previous_angle) {
  i <= 90;
  i = i + 1;
  myservo.write(i);
  delay(45);
};

```

It will compile, but probably not do what you want it to do. It should probably be:

```
for (int i=previous_angle; i<=90; i=i+1) {
  myservo.write(i);
  delay(45);
}

```

Also, `previous_angle` is never changed in your code after initialisation; it is always 0.

That also means that the `for` loop below will not do what you want (and that loop also doesn't increment `i` anywhere):

```
for (int i = previous_angle; i>0;)

```

There may be more; make the suggested changes first and see what happens.

---
Tags: c++, servo
---


# Question
Title: trigger a function of a Arduino Uno from signal received by LoRa module
I have two sx1278 Lora transceivers where both are connected to two Arduino Uno boards. I want to trigger a function in the Arduino Uno board where receiver side of LoRa connected using the signal received by Lora receiver.

# Answer
I'm assuming you have read the datasheet for the SX1278. If not, please refer to it at:

SX1278 Datasheet

On page 69 you will see a couple of tables regarding the functions possible on the digital I/O (i.e. DIO) pins:

I'm not clear what exactly you are looking for or which mode you are operating in (you have provided almost no information about your project) but all the information you might need is available on these DIO pins.

You can connect the appropriate pin or pins to some of the edge sensitive lines on your Arduino and define and enable an INTERRUPT in your code. So when the event you are waiting for happens, an interrupt will occur, you can go and read the data and do whatever with it.
> 1 votes

---
Tags: arduino-uno
---