# Question
Title: Motor for a winch (with controller and external power supply)
I'm in need of a motor or continuous servo to power a winch. The motor must be continuous\* and reversible, but it does not need to be fast, precise, nor bear a load when powered off. It just needs to overcome ~50 Newton of friction force (to winch open my bedroom curtains laterally).

(\* it needs to, given a discrete drum (maybe max 4cm diamater), winch about 1m)

I am using a MEGA2560 R3 which has a 5V port. I've tried using a 12V DC stepper motor (24BYJ48) with a standard ULN2003 controller, with a winch drum of ~2cm diameter, but it could not overcome the friction. I didn't spare much thought for the parameters of the arduino `Stepper` instance though; I just used a configuration which worked for winching lighter loads.

I'm a rookie, but I'm assuming my board cannot sufficiently power the motor(s) (I have 3), and possibly that they themselves are too weak. Hence I'm looking for a stronger motor and controller, controllable by my arduino, but which has a direct power supply (from mains). So:

* have I got this all wrong? Is it possible to arrange my 12V stepper motors to exert 50 Newton of tension, using the 5V supply from MEGA?
* is there a shield for my MEGA which can enable these motors to function in parallel?
* otherwise, is there a strong *continuous* servo with an external power supply that would work here?

# Answer
> Is it possible to arrange my 12V stepper motors to exert 50 Newton of tension, using the 5V supply from MEGA?

No, you should never ever power a motor through an Arduino. It can only provide a limited amount of current, before it gets fried. You need to provide the motor driver with voltage directly from your power source. You haven't stated, what you are using as a power supply. I assume, you are just using an USB port of a PC. That is also a no-go, since it will only provide 500mA at max (that's even less, than the Arduino can bear). You should power your motor with a power supply of 12V, since it is rated for that voltage. You can buy a simple wallwart for that.

Also, currently you are providing the 12V motor with only 5V, so it cannot give you it's full power. Use a power supply with the correct voltage and more than enough current capability. Though you should keep an eye on the current ratings of the ULN2003. The datasheet is not really clear, if that chip supports 12V supply voltage. Some variants like the ULN2004 seem to support it, but I'm not sure about the ULN2003. If it is not rated for 12V, you can destroy the chip that way.

We cannot know, if the motor with it's driver will be able to rotate the winch, since the seller does not name the torque of the motor. You could try to contact the seller and ask directly about this. More specialized sites, where you can buy motors, will tell you exactly, what the torque of the motor is, that you are buying. Buying a cheap part at Amazon is somewhat the lightweight variant of buying it directly from china: The documentation is a bit better, but still not great. Without documentation or information from the seller, you are stuck with just buying and trying.

> is there a shield for my MEGA which can enable these motors to function in parallel?

It isn't clear, what you mean by that. You can control as many motors simultaneously, as you have pins and as you have enough computation time (meaning not too much steps per second or other stuff going on in the program). As mentioned above the power has to be supplied to the drivers from outside of the Arduino, so that does not apply here.

> otherwise, is there a strong continuous servo with an external power supply that would work here?

Power supply and motors are 2 different parts, that aren't usually sold together. Also you should start with the motor: Look for a motor, that can provide the torque, that you need. Then look for a driver circuit, that can provide the functionality, is rated for the same voltage as the motor and can provide enough current for the motor (the max. motor current is also information, that a good seller will provide). Then look for a fitting power supply. Unless you are buying some kind of kit, you need to choose these parts yourself. (We don't do product recommendations here)

---

A possibility, that you might not have though about: You could buy a normal DC motor, which provides enough torque. As speed is not your biggest concern, you could buy a geared DC motor, which can be rather strong. For a driver you would need to buy or build a H-bridge controller (which is essentially just 4 transistors put together). Be sure to use a MOSFET based driver, if you want to buy a driver chip. The standard L298n is pretty lossy.

---

It seems, that you generally don't know, how to build such a project. So here are some notes, that might help you with that:

* **Connecting everything together:** In most cases (and especially when handling high current motors) you cannot get around soldering. You can buy a perfboard (cheap PCB material, with some pads already connected for ease of use), put the parts onto it and solder everything to the perfboard. Using shields as no-solder solution can only work, when you find a fitting shield and fitting motor for your requirements. That can be a far fetch. So if you want to get into electronics and Arduino, you probably should get yourself a soldering iron (there are also many tutorials about using it on the web).
* **Connecting the power supply:** When buying a walwart power supply, it will normally come with a cable attached to it. At the end of this cable may be a connector. You have 2 options: Cut the connector and solder the wires in the cable directly to your perfboard, or buy the counter part of the connector, which you then can solder to your perfboard. Depends on if you want to disconnect the power supply from the circuit or not.

As I'm suggesting here to invest in this a bit, I want to also sketch an alternative, if you just want to get it work and don't experiment (this site is full of makers, you do this for fun, but that does not have to apply to everyone):

You may be able to use a shield to do, what you want to. This might cost a more, than putting the parts together yourself, but it will safe you the investment in tools, which you might not need in future. As above you need to choose the parts fitting your requirements. Decide on the type of motors, that you want to use (if money is not such a deal, you can nearly use any motor with enough power, stepper motor, DC motor, ...). Look for a shield, that can provide the needed current and voltage to the motor.

Every motor shield has a terminal for connecting the external power supply for the motors. On good shields this is a screw terminal, so you would simply strip the cable of the power supply and put the wires of it into the screw terminal.
> 1 votes

# Answer
"Is it possible to arrange my 12V stepper motors to exert 50 Newton of tension, using the 5V supply from MEGA?"

Huh? Do you mean can you power a 12V stepper directly from the 5V supply on an Arduino? How would that work? You need an external power supply and a motor controller that converts the 5V control signals from the Arduino to 12V. The answer is "absolutely not." Motors draw way, way too much current to be powered from an Arduino logic pin, and all but the smallest motor will draw too much current for the 5V supply line. Plus you said you were using a 12V motor. You can't run a 12V motor on 5V.

A stepper seems like the wrong tool for this job. You should be able to use a high torque 12V DC motor and an H-bridge motor controller. An H-bridge will let you run the motor forwards or backwards.

You'll probably need a motor with a gearbox, since you likely want a fairly slow turning shaft. How many newton-meters/second do you need?
> 0 votes

---
Tags: arduino-mega, servo, arduino-motor-shield, stepper-motor
---


# Question
Title: How to load scal factor external to the code?
We know that, we need calibration factors (scale factors) to read current sensor data (ACS758) to arduino. I am also using voltage reader using voltage divider circuit for my project. I need to build 5 such boards and need to change calibration factor in main program everytime due to tolerance of componenets. Currently for one of my board reference\_factor is 0.81 and this will change due to resistor tolerance for other boards.

Because of this issue I need to maintain 5 different codes for 5 different boards. These sensor values controls on and off of certain relays. (Not shown in the code).

can I load this referrence\_factor externally through text file or as any other medium so that I need not change the code everytime.? I am using arduino Nano.

```
int reference_Factor = 0.81;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
}

void loop() {
  // read the raw data coming in on analog pin 0:
  int lightLevel = analogRead(A0);
  // Convert the raw data value (0 - 1023) to voltage (0.0V - 5.0V):
  float voltage = lightLevel * reference_factor;
  // write the voltage value to the serial monitor:
  Serial.println(voltage);
}

```

# Answer
> -1 votes
As written in the comments you coulduse eepron, but in your scenario it has one big disadvantage: Everything has to be written at compile time (aka when you programm the Nano, you have also to fill the eeprom with the relevant values), so e.g. if you have a temperature depending factor you want to change while on the field...
I would go for a SD-card reader:

* Cheap to get (2$)
* Easy to handle in code (read from a file is a standard function)
* using a PC compatible file systen FAT enables reading/writing onto the SD card on a PC/other device without recompiling your code.
* If you switch sensors for whatever reason, just write a new scale.txt file to the SD-card, insert and reboot the nano to get the new values
* you could still use eeprom as a fallback scenario

As a tip (also mentioned in the comments by Delta\_G) int for something like 0.01 is not what you want - define as float and watch out for the "conversion trap" when using with other variables not defined as float.

---
Tags: arduino-ide, arduino-nano, atmega328
---


# Question
Title: Building projects on the command line using the Bare-Arduino-Project template
I'm trying to program an Adafruit Trinket using avr-gcc et. al. with the Makefile from the Bare-Arduino-Project on macOS Catalina.

I can build projects for standard boards like the Uno, but not for the Trinket. Everything works as expected using the "official" Arduino IDE (1.18.10). In the Bare-Arduino-Project Makefile I'm specifying the Trinket as:

```
BOARD_TAG         = trinket5
BOARD_SUB         = attiny85

```

I get an error from avr-gcc that **mmcu** is not defined. I assume this is because the command line tools aren't finding the Adafruit equivalent of *boards.txt*. When I look in the Arduino IDE package I don't find the Adafruit boards in *boards.txt* or anything that looks like the definitions for the Adafruit boards (despite having added them in the IDE).

Any ideas about how to set up support for the Trinket (or other third party boards) when using command line tools?

# Answer
> 1 votes
You probably look at the wrong `boards.txt`:

```
# Trinket 5V Configuration
trinket5.name=Adafruit Trinket (ATtiny85 @ 16MHz)

```

this can be found in the `boards.txt` in the main directory

```
C:\Users\YOUR_USER_NAME\AppData\Local\Arduino15\packages\arduino\hardware

```

in the sub directory

\adafruit\avr

in the same main directory should also be a folder named `1.8.2` (for ArduinioIDE 1.8.12) for the core files

if added via board-manager using this line in preferences/additional bord manager urls

```
https://adafruit.github.io/arduino-board-index/package_adafruit_index.json

```

If you did a manual installation check with this guide for pit traps.
Details on using trinket with the avrdude command line can be found here

---
Tags: command-line
---


# Question
Title: Is there a way to remove the 8.3 filename limitation on the SD.h library?
I need to be able to create text files on my SD card that are with names longer than 8 characters (which is what the SD.h currently limits me to). A choice would be to move to the SDFat library but before considering that option, is there a way to just remove the limit on the SD.h (because my code already implements the good-old SD.h)? What would be the best way to go about this issue?

# Answer
> 1 votes
The 8.3 "limit" is not a "limit" that can be removed. It is how FAT filesystems work. Longer filenames are a "fudge" extension overlaid on top of that fileststem structure. To be able to use them you would need to implement that extension.

Simpler to switch to a more modern implementation. FatFS is your friend:

* LFN support, including UTF
* Faster device access
* More efficient
* Can handle more devices than just SD cards
* Can handle multiple devices at once

There is an implementation here though I don't know how good it is (I use it on chipKIT where it is bundled by default).

If you can't get FatFs then basically *anything* is better than the SD library to be brutally honest.

---
Tags: library, sd-card, sd.h
---


# Question
Title: Having trouble assigning colour to my neopixels
Hi I was wondering if someone is able to help me! I am currently trying to get a strip of 10 neopixels to change colour. I want to be able to code a random neopixel in the strip to change to either red, blue, green and yellow consecutively after 2 seconds. I am relatively new to Arduino so I'm still learning. I have been using the code below and it does everything that I want it to but I would like to set the colour so they're not as randomised. I found this code online.

```
#include <Adafruit_NeoPixel.h>

#define PIN 6
#define LED_COUNT 50
Adafruit_NeoPixel strip = Adafruit_NeoPixel(LED_COUNT, PIN, NEO_RGB + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop()
{
  randomPixelColor(100);

}

void randomPixelColor(int wait)
{
  int i= random(strip.numPixels());

  uint32_t c = random(2147483647); // I have no idea what this crazy number does.
  strip.setPixelColor(i, c);
  strip.show();
  delay(1000);

}    // end void randomPixelColor()

```

I don't even know if this is the right code to be using! Hopefully someone can help me cause I'm so confused.

# Answer
> 1 votes
You already are choosing a random LED. Now you only need to define and use the colors, that you need. Define an array with the colors:

```
#define COLOR_N 4
uint32_t colors[COLOR_N] = {0x00FF0000, 0x000000FF, 0x0000FF00, 0x00FFFF00};

```

Also define a static or global variable to hold the current color:

```
uint8_t current_color = 0;

```

Then use this array in `strip.setPixelColor()` with the `current_color` variable as index:

```
strip.setPixelColor(i, colors[current_color]);

```

Now increment `current_color` for the next color. To go from yellow to red again, you can use the modulo operator `%`:

```
current_color = (current_color + 1) % COLOR_N;

```

You can easily extend to more colors, by writing the new colors into the `colors` array and setting `COLOR_N` to the corresponding value.

---

**About the color values**: The neopixels use an RGB color model with 8 bit depth. That means, that each component (red, green and blue) occupies exactly 1 byte. Thus there are 256 steps for each component. To describe a full color, you need all three components, thus 3 bytes or 24 bits. The data type, that fits this `uint32_t` (unsigned integer with 32 bit), though the most significant byte is unused here (if you use an RGBW strip, this byte is the component for the white LEDs).

We can write the number, that is representing a full color, as a hexadecimal value. Each component occupies 2 hexadecimal digits:

```
0x00RRGGBB

```

where `0x` is the prefix, which marks a hexadecimal number, and `RR`, `GG` and `BB` are the components red, green and blue of the color. So a full red is `0x00FF0000`, a full blue is `0x000000FF` (the leading zeros are not mandatory, but I think they help readability and comparability).

The color mixing works additive here, just like light does. All components mixed together at the same ratio gives you white, all components to zero means black. Thus you get yellow from mixing red and green the same ratio. So a full yellow is `0x00FFFF00`.

---
Tags: neopixel
---


title: Do Loop query not stopping

text:
# Question
Title: Do Loop query not stopping
I am new to Arduino programming and I would like to ask a question.

Firstly apologies if this has been answered before and I understand if it gets locked if this has been answered elsewhere.

I am trying to get three LED's (red, amber, green) to loop 5 times (in a do loop).

for this I have created a integer variable (x) and initialised the variable to 0.

I then increase x by 1 each time.

However I cannot get them to stop looping when x is greater than 5. The program does work as expected for everything else (green LED lit, wait 1 sec, Yellow LED lit, wait 1 sec, red LED lit and then loop).

```
   //set LED pins
int greenPin = 13;
int yellowPin = 12;
int redPin = 11;

void setup()
{
  pinMode(greenPin, OUTPUT);      // sets the digital pin as output
  pinMode(yellowPin, OUTPUT);
  pinMode(redPin, OUTPUT);
}

void loop(){
int x = 0;

 do {
  digitalWrite(greenPin, HIGH);   // sets the LED on
  delay(1000);                  // waits for a second
  digitalWrite(greenPin, LOW);
  digitalWrite(yellowPin, HIGH);    // sets the LED off
  delay(1000);
  digitalWrite(yellowPin, LOW);// waits for a second
  digitalWrite(redPin, HIGH);    // sets the LED off
  delay(1000);
  digitalWrite(redPin, LOW);
 }
   while(x<=5); {
    x = x + 1;
   }
}

```

# Answer
Chrisl already gave the clue.

However, to add a comment with a code example I use the answer box.

In C you have more or less two kind of loops:

* for
* do / while

The first one is when you know beforehand how many iterations you have, the second when it depends on external input (e.g. when you expect a value acquired from within the loop).

In your case, you can better use the `for` loop, so you get:

```
for (x = 0; x < 6; x++)
{
   ...
}

```

What this does i:

1. Initializes x to 0 (first part of the `for` statement)
2. It checks the condition `x < 5' (second part of the`for`statement). If false, it continues with the first statement after the`for\` body (after the } bracket).
3. It runs the body of the loop (inside the brackets)
4. It increases x (third part of the `for` statement)
5. It continues with 2

Also it is quite common for the condition to include the start element of the ragne (x = 0), but exclude the end element of the range (x \< 6), thus it runs the last time with x == 5.
> 1 votes

---
Tags: programming, loop
---


# Question
Title: Data type explanation regarding analogRead of a photoresistor
This is a fundamental question - very new (1st post) and trying to learn. I have a photocell connected in series with a 10kOhm resistor between 5v & Gnd (to make a voltage divider) and the divided voltage is connected to A1. In my code, when I specify the datatype as uint8\_t I get values around the 200 range, yet when I change the type to uint16\_t the values change to 1000 range. Where should I be looking to understand this behavior?

# Answer
You should keep it `uint16_t`.

See: analogRead.

It shows the return value is a 10 bit number, which means a value of 0 to 1023.

If you use `uint8_t`, which is an 8 bit value, it only can store values from 0-255. This means if the value is higher, the most significant bits are clipped/removed, and you only have the value module 256 left.

With a 16 bit value, you will have the left 6 bits unused, but this does not matter. It has the 10 bits you get from the `analogRead` function. Example

Assume the value is 1000, which is in binary:

```
11 1110 1000

```

Written in 16 bits (using uint16\_t), move it to the right and prefix with zeros you get:

```
0000 0011 1110 1000

```

However, if you try to store this in 8 bits (using uint8\_t) you get:

```
(removed) 1110 1000

```

Which is the value 232 instead of 1000.

Some guidelines:

* Always use a type that fits the value you want to store (in worst case).
* If you know for sure your value will be non-negative, use an unsigned type (e.g. `uint8_t`).
* If you want to preserve memory (or good practice) use a value that is not necessarily big (thus if you know a value will never be more than 1023 like in your case, don't use `uint32_t`).
> 2 votes

---
Tags: analogread, data-type
---


# Question
Title: Condition in a while loop not updated on my mkr1010
I am using a server-client system where i send data from the server to the client to turn on a led (the onboard led). Led must be turned off using digital input (labeled 7 on the connector). I use therefore a while loop that checks the value of the input (button press). As long as value is not equal to LOW the led remains on (i use also a second led on pin 13 as doublecheck). I assume that the while loop will be left once i press the button, unfortunately this doesn't happen. The result of the condition seems not updated (remains HIGH). I measured the voltage on the input when pressing the button and it goes from 3.3V to 0.0V so hardware seems to be OK. From my undestanding the while loop is always (before each loop) checking the condition ? why doesn't this happen here ? did i do something wrong ? I must use a while because i never know in advance when the button will be pressed.

this my code :

```
#include <SPI.h>
#include <WiFiNINA.h>
#include <utility/wifi_drv.h>
#include "arduino_secrets.h"
///////please enter your sensitive data in the Secret tab/arduino_secrets.h
char ssid[] = SECRET_SSID;        // your network SSID (name)
char pass[] = SECRET_PASS;    // your network password (use for WPA, or use as key for WEP)

//int keyIndex = 0;            // your network key Index number (needed only for WEP)

const int buttonPin = 7;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin
int buttonState;         // variable for reading the pushbutton status

int status = WL_IDLE_STATUS;
IPAddress ServerIP(192,168,0,157);
WiFiClient client;

int i;
String response;

void setup() {

  WiFiDrv::pinMode(25, OUTPUT); //GREEN
  WiFiDrv::pinMode(26, OUTPUT); //RED
  WiFiDrv::pinMode(27, OUTPUT); //BLUE

 pinMode(buttonPin, INPUT);
 pinMode(ledPin, OUTPUT);

  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
   ; // wait for serial port to connect. Needed for native USB port only
  }
  // check for the WiFi module:
  if (WiFi.status() == WL_NO_MODULE) {
    Serial.println("Communication with WiFi module failed!");
    // don't continue
    while (true);
  }

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
  Serial.println("Please upgrade the firmware");
  }

  // attempt to connect to Wifi network:
  while (status != WL_CONNECTED) {
    Serial.print("Attempting to connect to SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // wait 10 seconds for connection:
    delay(10000);
  }

    // you're connected now, so print out the status:
  printWifiStatus();
}

void loop() {

if (client.connect(ServerIP, 23)) {
  client.print("90");
  String response = client.readStringUntil('\n');

  Serial.println(response);

if (response == "9") {
  buttonState = digitalRead(buttonPin);
 // Serial.println(buttonState);
  while (buttonState != LOW){
    // turn LED on:
    digitalWrite(ledPin, HIGH);
     WiFiDrv::digitalWrite(25, 255); // for full brightness
     Serial.println(buttonState);
  }
  digitalWrite(ledPin, LOW);
  WiFiDrv::digitalWrite(25, LOW); // for full brightness
        }
  }

  client.stop();
}

void printWifiStatus() {
  // print the SSID of the network you're attached to:
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your board's IP address:
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
 Serial.println(ip);

  // print the received signal strength:
  long rssi = WiFi.RSSI();
  Serial.print("signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}

```

thanks a lot for helping me out !

# Answer
> 2 votes
```
 while (buttonState != LOW){
    // turn LED on:
    digitalWrite(ledPin, HIGH);
     WiFiDrv::digitalWrite(25, 255); // for full brightness
     Serial.println(buttonState);
  }

```

You never update the value of buttonState in this while loop. If buttonState is not LOW to get into the while loop, nothing inside the while loop will ever change it so every time it gets checked it will still not be LOW. It's not going to surmise that you meant to read a pin just because you used that variable to read a pin once before.

But do you really need this while loop? Couldn't you just write the led pin low when you first get a press and then write it high when it first gets released? See the "State Change Example". Let the loop function be the loop. It will lead to better code. You don't see this now because you are a novice, but you are about to paint yourself into a corner with this approach and you'll soon be rewriting the whole thing. It's a trap that gets most new coders. Better to get it right now.

---
Tags: arduino-ide, led, code-review, mkr1010
---


# Question
Title: Linux not recoginizing Arduino Mega2560 Clone
I have an Elegoo Mega2560 R3. On my Windows machine, it recognizes fine and loads exactly like a Mega2560. I have a System76 laptop running Pop\_os!. When I attach the board, I cannot connect to the port in Arduino studio (reinstalled today with newest version).

When I check, I don't see the ttyACM1 device (ACM1 specifically because of items listed below).

`lsusb before plugging in`

```
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 5986:9102 Acer, Inc BisonCam,NB Pro
Bus 001 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 004: ID 8087:0aaa Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

```

`lsusb after plugging in`

```
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 5986:9102 Acer, Inc BisonCam,NB Pro
Bus 001 Device 020: ID 2341:0010 Arduino SA Mega 2560 (CDC ACM)
Bus 001 Device 002: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 004: ID 8087:0aaa Intel Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

```

`dmsg after plugging in`

```
[65178.203006] usb 1-6: new full-speed USB device number 19 using xhci_hcd
[65178.353353] usb 1-6: New USB device found, idVendor=2341, idProduct=0010, bcdDevice= 0.01
[65178.353359] usb 1-6: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[65178.353363] usb 1-6: Product: Arduino Mega 2560
[65178.353366] usb 1-6: Manufacturer: Arduino (www.arduino.cc)
[65178.353369] usb 1-6: SerialNumber: 7563331323335130F170
[65178.357650] cdc_acm 1-6:1.0: ttyACM1: USB ACM device

```

`ls /dev/tty*`

```
**/dev/tty**    **/dev/tty23**  **/dev/tty39**  **/dev/tty54**      **/dev/ttyS10**  **/dev/ttyS26**
**/dev/tty0**   **/dev/tty24**  **/dev/tty4**   **/dev/tty55**      **/dev/ttyS11**  **/dev/ttyS27**
**/dev/tty1**   **/dev/tty25**  **/dev/tty40**  **/dev/tty56**      **/dev/ttyS12**  **/dev/ttyS28**
**/dev/tty10**  **/dev/tty26**  **/dev/tty41**  **/dev/tty57**      **/dev/ttyS13**  **/dev/ttyS29**
**/dev/tty11**  **/dev/tty27**  **/dev/tty42**  **/dev/tty58**      **/dev/ttyS14**  **/dev/ttyS3**
**/dev/tty12**  **/dev/tty28**  **/dev/tty43**  **/dev/tty59**      **/dev/ttyS15**  **/dev/ttyS30**
**/dev/tty13**  **/dev/tty29**  **/dev/tty44**  **/dev/tty6**       **/dev/ttyS16**  **/dev/ttyS31**
**/dev/tty14**  **/dev/tty3**   **/dev/tty45**  **/dev/tty60**      **/dev/ttyS17**  **/dev/ttyS4**
**/dev/tty15**  **/dev/tty30**  **/dev/tty46**  **/dev/tty61**      **/dev/ttyS18**  **/dev/ttyS5**
**/dev/tty16**  **/dev/tty31**  **/dev/tty47**  **/dev/tty62**      **/dev/ttyS19**  **/dev/ttyS6**
**/dev/tty17**  **/dev/tty32**  **/dev/tty48**  **/dev/tty63**      **/dev/ttyS2**   **/dev/ttyS7**
**/dev/tty18**  **/dev/tty33**  **/dev/tty49**  **/dev/tty7**       **/dev/ttyS20**  **/dev/ttyS8**
**/dev/tty19**  **/dev/tty34**  **/dev/tty5**   **/dev/tty8**       **/dev/ttyS21**  **/dev/ttyS9**
**/dev/tty2**   **/dev/tty35**  **/dev/tty50**  **/dev/tty9**       **/dev/ttyS22**
**/dev/tty20**  **/dev/tty36**  **/dev/tty51**  **/dev/ttyprintk**  **/dev/ttyS23**
**/dev/tty21**  **/dev/tty37**  **/dev/tty52**  **/dev/ttyS0**      **/dev/ttyS24**
**/dev/tty22**  **/dev/tty38**  **/dev/tty53**  **/dev/ttyS1**      **/dev/ttyS25**

```

# Answer
> 1 votes
Running avrdude as root works.
Adding permissions to ttyACM0/ttyACM1 for everybody also works. Execute

```
 sudo chmod 777 /dev/ttyACM0
 sudo chmod 777 /dev/ttyACM1

```

and after that you should be able to compile and upload the code to the arduino The only issue with this is that you have to run that line everytime you connect the Arduino to the USB because ttyACM0/ttyACM1 is recreated. So as pointed in the comment if thats the case than you add dialout group to your user, log out, then log in again, you should have access to the Arduino serial.

```
 sudo usermod -a -G dialout yourUserName

```

---
Tags: arduino-mega, linux
---


# Question
Title: Using SDA and SCL with analog inputs at the same time
I'm trying to build a robot arm based on Arduino UNO and PCA9685 controlled by few potentiometers. The easiest way that I figure out and find on internet is using two Arduino's, one as master and second as slave. This is where my question comes from, there is a way to use single Arduino UNO instead of two by using at the same time SDA and SCL with analog inputs? Maybe there is another way to do that?

That's my actual code:

```
#include <Arduino.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwmDriver = Adafruit_PWMServoDriver(0x40);

void setup()
{
  pwmDriver.begin();
  pwmDriver.setPWMFreq(51);
}

int tempPotVal = 0;
int adcPin[4] = {A0, A1, A2, A3};
int pwmRisingTime = 0;
int pwmFallingTime = 0;

void loop()
{
  for (int id = 0; id < 4; id++)
  {
    tempPotVal = analogRead(adcPin[id]);
    pwmFallingTime = map(tempPotVal, 113, 842, 102, 512);
    pwmDriver.setPWM(id, pwmRisingTime, pwmFallingTime);
  }
}

```

# Answer
I2C on Uno/Nano/Mini uses only pins labeled A4 and A5. you can still use 4 ADC pins A0 to A3 on Uno.
> 0 votes

# Answer
No. You can't. Not unless you could come up with some way of disconnecting one set of devices and connecting the other.

Instead you could add an I2C ADC chip to the existing SCL/SDA bus to expand the number of ADC channels you have available. Or use an analog MUX chip on one of the other ADC pins to expand the number of devices you could connect to it. Or you could add an SPI ADC chip to pins 10-13 (SPI bus) to give you more analog inputs.
> 0 votes

---
Tags: i2c, pwm, analogread, adafruit
---


title: Using different variables in a function

text:
# Question
Title: Using different variables in a function
I have a function `SetTFgr(float T, int FGr)` to set the time and filtergrade of my LED enlarger.

It works without a problem and changes the values of `T` or `Fgr` according to the buttons I press. Both `T` and `FGr` are global variables.

Now I want to use the same funtion with different variables. When I call the function with `SetTFgr(TExp[i], FGrExp[i])` I would expect the function to work with the values of `TExp[i]` or `FGrExp[i]` and increase/decrease these values. It does not, it appears to use the value of `T` or `Fgr` instead.

How can I get what I am after?

# Answer
To be clear, you want to read the values of buttons (meaning unspecified) and use those values to set a float and an int variable. Further, you want to write a function that takes a couple of parameters that specify where you want to store those button values?

That is an unusual way to use function parameters. Usually function parameters specify an input value, and then you use that value to do something. Instead, you want to have the inputs be globally available readings (button values) and have the function parameters specify where to store those values.

C and C++ function parameters are usually passed "by value". That means that what gets sent to the function is a value, not a pointer to the variable that contains that variable. Thus the called function can't change the original variable.

If you want to pass a pointer to the variable, you have to use the `&` "address of" operator to pass the variable "by reference".

Your function might look like this using C++ pass by reference syntax:

```
void SetTFgr(float &T, int &FGr) {
    float input_T = //figure out button value for T
    T = input_T;
    int input_FGr = //figure out button value for Far
    FGr = input_FGr;
}

```

Then you'd invoke it like this:

```
SeTFgr(T, FGr);

```

You could also accomplish the same thing using C pointer syntax.
> 1 votes

# Answer
Parameters of functions in C++ are by value. So `T` in your function is not the variable you use to call the function. It only has the same value. Use `float& T` to pass the reference to the variable.
> 0 votes

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


# Question
Title: Tilt Compensated Compass Using HMC5983 gives inconsistent output
I've been trying to build a tilt compensated compass for an autonomous Arduino car I'm building. I'm having issues with the consistency of my data.

This is the code I'm using.

```
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050_6Axis_MotionApps_V6_12.h>
#define Magnetometer_addr 0x1E
MPU6050 mpu;

bool dmpReady = false;
uint8_t mpuIntStatus;
uint8_t devStatus;
uint16_t packetSize;
uint16_t fifoCount;
uint8_t fifoBuffer[64];
float prevoius_corrected_reading,corrected_reading;

Quaternion q;
VectorFloat gravity;
float ypr[3];

bool mpuInterrupt = false;

float Xerror = 0.01;
float Yerror = -0.385;
float Zerror = -0.17;

int X0, X1, Z0, Z1,Y0, Y1;
float X, Y, Z;
float compass_heading;

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

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x01);
  Wire.write(0x00);
  Wire.endTransmission();

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission();

  mpu.initialize();
  //Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
  devStatus = mpu.dmpInitialize();

    mpu.setXGyroOffset(51);
    mpu.setYGyroOffset(8);
    mpu.setZGyroOffset(21);
    mpu.setXAccelOffset(1150);
    mpu.setYAccelOffset(-50);
    mpu.setZAccelOffset(1060);

    if (devStatus == 0) {

        mpu.CalibrateAccel(6);
        mpu.CalibrateGyro(6);
        //Serial.println();
        mpu.PrintActiveOffsets();
        mpu.setDMPEnabled(true);
        dmpReady = true;
        packetSize = mpu.dmpGetFIFOPacketSize();
    } else {
        //Serial.print(F("DMP Initialization failed (code "));
        //Serial.print(devStatus);
        //Serial.println(F(")"));
    }

  delay(20);

}

void loop() {

  compass_heading = request_compass_data();

  Serial.print("Raw compass heading is \t");
  Serial.print(compass_heading);

  Serial.print("\t\t");

  request_accel_data();

  Serial.print("YAW\t:");
  Serial.print(ypr[0] * 180/M_PI);
  Serial.print("\tROLL\t:");
  Serial.print(ypr[1] * 180/M_PI);
  Serial.print("\tPITCH\t:");
  Serial.print(ypr[2] * 180/M_PI);

  prevoius_corrected_reading = corrected_reading;

  Serial.print("\tCorrected compass heading is \t");
  float Xhor =  X*cos(ypr[2]) + Z*sin(ypr[2]);
  float Yhor =  Y*cos(ypr[1]) - Z*sin(ypr[1])*cos(ypr[2]) + X*sin(ypr[1])*sin(ypr[2]);

  corrected_reading = rad_to_deg(rad_ang(Yhor, Xhor));
  Serial.print(corrected_reading);

  Serial.print("\tFiltered compass heading is \t");

  Serial.print(0.1 * corrected_reading + 0.9 * prevoius_corrected_reading);
  Serial.println();

}

float rad_ang(float a, float b){
  float ang = atan2(a, b);
  if(ang<0){ang += 2*PI;}
  if(ang>2*PI){ang -= 2*PI;}
  return ang;
}

float rad_to_deg(float rad_in){
  return rad_in / PI * 180;
}

float request_compass_data(){
  //return compass heading
  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x03);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  X0 = Wire.read();
  }

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x04);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  X1 = Wire.read();
  }

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x05);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  Z0 = Wire.read();
  }

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x06);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  Z1 = Wire.read();
  }

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x07);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  Y0 = Wire.read();
  }

  Wire.beginTransmission(Magnetometer_addr);
  Wire.write(0x08);
  Wire.endTransmission();
  Wire.requestFrom(Magnetometer_addr,1);
  if (Wire.available()>=1){
  Y1 = Wire.read();
  }

  X0 = X0<<8;
  Z0 = Z0<<8;
  Y0 = Y0<<8;

  X = X1 + X0;
  X -= Xerror;
  Y = Y1 + Y0;
  Y -= Yerror;
  Z = Z1 + Z0;
  Z -= Zerror;

  //Calibrated manually
  X = X * 0.00092 - Xerror;
  Y = Y * 0.00092 - Yerror;
  Z = Z * 0.00092 - Zerror;
  /*
  Serial.print("XYZ\t");
  Serial.print(X);
  Serial.print("\t");
  Serial.print(Y);
  Serial.print("\t");
  Serial.println(Z);
*/
  float dir = rad_to_deg(rad_ang(Y, X));

  return dir;

}

void request_accel_data(){
        if (!dmpReady) return;
    mpuInterrupt = true;

    while (!mpuInterrupt && fifoCount < packetSize) {
        if (mpuInterrupt && fifoCount < packetSize) {
          fifoCount = mpu.getFIFOCount();
        }

    }

    mpuInterrupt = false;
    mpuIntStatus = mpu.getIntStatus();
    //Serial.print("INT STATUS:\t");
    //Serial.print(mpuIntStatus);
    fifoCount = mpu.getFIFOCount();
    //Serial.print("\tFIFO COUNT:\t");
    //Serial.print(fifoCount);

    if ((mpuIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024) {

        mpu.resetFIFO();
        fifoCount = mpu.getFIFOCount();
        Serial.println(F("FIFO overflow!"));

    }

    else if (mpuIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)) {
        while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
        mpu.getFIFOBytes(fifoBuffer, packetSize);
        fifoCount -= packetSize;
        mpu.dmpGetQuaternion(&q, fifoBuffer);
        mpu.dmpGetGravity(&gravity, &q);
        mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
        mpu.resetFIFO();

    }
}

```

When I have the below sensor orientation my data output(corrected\_reading) varies as shown in the below graph on one complete rotation.I'm happy with this output as there is only very little inconsistency and the tilt compensation works fine too.

However keeping them in the above orientation within my car is not practically possible in my case. So I tried this orientation.

But no matter how I adjust my code to suit this orientation I always end up getting very inconsistent data like below.

I'm sure that there is some mistake i'm making in the second orientation i used.The biggest problem is that the raw magnetometer output(compass\_heading) also becomes inconsistent in this case.

Please give me your suggestions as to what changes I should make in order to get a smooth output with the second orientation. Thanks in advance.

Microcontroller - Arduino Uno Magnetometer - HMC 5983 Accelerometer - MPU 6050

# Answer
> 0 votes
As it is not possible to reproduce the errors and analyse the program in detail, the thing which jumped at me that you have no gliding error correction (or its hidden in a library) for the compass (The MPU6050 has probably one as FIFO is called but you should look it up). The method is easy to explain:

* You take an array of lets say 20 measure points.
* You apply FIFO First value in is the last out
* you do gliding average over the first 15 values -\> this is the orientation output
* the last 2 are used for value validation:
    + if you get a value out of a defined data range AND the next is in the range then ditch the before value (error corection)
    + if you get a value out of a defined data range AND the next 4 values are also in the range compared tothe first out of range this will cause the array to empty and start a new gliding average with these values. (Might not be the case when driving a car but in plane models this can happen -\> 180 degree turns)

Its up to you how many values you take as a base reference and how many lead to an aprupt direction change. As we are in hobby electronics you can not expect high quality value delivery sowe have to use math to get to a desired result.
Regarding the changed orientation of the magnetometer.
**EDIT**
In my experience the turning of the magnetometer upside down resultedin weird behavior and more unstable readings. I guess this is due to the elctronics shielding now from the top rather than the bottom.
For reading and error handling I looked \[into this library code\]((https://github.com/keepworking/Mecha\_QMC5883L/blob/master/MechaQMC5883.cpp) and adapted the read routine to my needs. Also lookat the examplesfor valuable input.

---
Tags: arduino-uno, sensors, accelerometer, magnetometer
---


# Question
Title: Is there a way to reuse an old robot using arduino?
I had purchased a simple robot (named Qu-Bot) for a school project a couple of years ago. After the project, it just went into the attic. A few days ago, I purchased an Arduino Uno and started learning the how to operate it. But, before I could purchase LEDs, sensors, LCD, etc, a total lockdown was implemented in my country due to coronavirus.

Is there a way I could program that old robot in Arduino IDE like I program my Uno?

> I'm not sure if this is useful or not, but, when I execute `$ lsusb` , the bot appears as `Bus 001 Device 018: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port`

Here's a link to some documentation of the bot: http://www.technogravity.com/products/qu\_bot/qu\_bot\_downloads.php

Here are photos of all the 3 chips I can see on the board of the bot:

# Answer
As to your question can I program in ArduinIDE - Yes.

* The main chip is from AVR ATMEGA16,
* the LCD is a 16x2 (pinout for use with the LCD library is enclosed)
* motor driver is (Big thanks to Juraj not a mystery) a ULN2803. Example to work with can be found here.

The circuit diagram enclosed:

How to use in ArduinoIDE:

* First install the driver for prolific and makes sure your OS finds the robot (done)
    + Then install the MightyCore which supports ATMega16 \- there are detailed instructions how to do it
    + Start with a blink led example (pins from the schematic) compile and upload to test
    + Then a simple LCD example and so on.

Another posibility would be tor scrap the bot and salvage most parts.

If its feasable the Manual will tell you which parts can be removed without soldering
To get started you need the USB drivers for OS and the original SW to test wether the QBot is still ok from a hardware perspective, Than you can salvage the parts from it to use with Arduino:
Than you have to make a new base plate (google for pics of 2-wheel robot base plates) and get a motor driver (I recommend for a beginner a cheap motor shield like an Adafruit V2 motor shield clone 5-7$). As you probably have downloaded ArduinoIDE latest version for your OS, get some example programs and start to play around.
> 1 votes

# Answer
On your linked website I wasn't able to open the sample programs (404 Not Found). The site seems very outdated (it has news from 2015 on it). So I cannot be sure, how the robot is meant do be programmed.

But: The Atmega16A is a programmable microcontroller and it most likely is the brain of the robot. Depending on how the original bot was programmed, you can have 2 ways to go:

1. If it was originally build around the Arduino platform, meaning, that it already has a fitting bootloader in it, then you might be able to program directly over USB/Serial from the Arduino IDE.
2. If not you can program it with the Arduino IDE over ISP by using your Arduino Uno as a programmer. Look at this documentation site for a more detailed description, how this is done. Note, that you will most likely have to remove the Atmega from the bot for programming, since the programming can interfere with the circuit of the bot (The Atmega seems to be in a socket, so that you can remove it from there). After programming you can put it into the bot again.

In both cases you need to install the correct core for that chip in the Arduino IDE, for example by following this guide (found by a quick search, not tested). (Maybe you even can find a core specifically for that robot)

---

The other shown chips seem to be the motor drivers.
> 0 votes

---
Tags: arduino-ide
---


title: Controlling Brickstuff with Arduino

text:
# Question
Title: Controlling Brickstuff with Arduino
I don't have much experience with electronics (I'm ok with programming). I have some Brickstuff lights in a Lego set. The lights are powered by 3 AA batteries. The Brickstuff documentation says that I should not connect then directly to an Arduino, as the current exceeds the Arduino limit. I want to use an Arduino to power the lights and activate them with a button, but I want to use the same power supply to feed the Arduino and the lights.

Any suggestions about what components I should use, and how to connect them? Thanks.

# Answer
> 0 votes
Transistor is likely what you want for simplicity.

Be sure to add up all your amperage requirements and then add some extra when selecting a supply. Having too little available will make your circuit misbehave while having a supply capable of giving you more doesn't hurt.

For voltage 3×1.5V = 4.5V if the batteries are in series. Arduino runs on 5V (USB). I suspect you'll probably be using a 5V supply. Both circuits have a little margin, lights usually more so.

---
Tags: arduino-uno
---


# Question
Title: Why do I keep blowing up Nanos when I solder them?
I have blown up 2 Arduino Nanos and I'm trying to figure out what I'm doing wrong.

In both cases, I was powering the boards with a 16V supply (I know this is high, but the regulator datasheet says it is good to 25V, and the regulator was not damaged). I unplug the supply and USB cable and then start soldering to one of the pins (A6). When I plug the board back in, the L LED does not flash, indicating the bootloader has been erased. The POW light is on and I still measure 5V, indicating the regulator is working. When I connect the board to my PC, the serial port pops up just fine. But when I try to upload a sketch, the IDE times out and says it cannot communicate with the board.

I attempted to reprogram the bootloader using a raspberry pi but avrdude also says it cannot find the device either. It looks like the microcontroller is blown.

My iron tip is grounded, so my best guess is some residual power in the supply travels through the microcontroller to my iron and shorts something out. But this seems unlikely seeing as A6 is an input and grounding it should be just fine even when the supply is fully on.

Any ideas what I could be doing wrong? FYI, I am cross-posting this on the Arduino forums.

# Answer
> 0 votes
My advice would be not to solder directly to the Nano pins. Instead, use the appropriately sized DIL socket, and solder to the pins of that instead. Then plug in the Nano once the soldering is complete.

---
Tags: arduino-nano
---


# Question
Title: C3 not declared in this scope when running MIDI example code
I'm trying to run the MIDI example from Arduino.CC in Arduino Studio.

I am using an Arduino Leonardo, which has USB HID capabilities. I have installed the library as mentioned:

When I press the compile or upload button, it says:

```
'D3' was not declared in this scope

```

What's wrong? How do I fix this?

# Answer
The pitches for the notes are taken from pitchToNote.h. In there you can see definitions for the notes like:

```
#define pitchC3  48

```

It seems that the names were changed from `C3` to `pitchC3`.

I am not 100% sure, but my guess is that this was done to avoid conflicts between the note `A3` and the analog input `A3` (and silimar).

So, in line 25 of the example code, add `pitch` for all notes:

```
const byte notePitches[NUM_BUTTONS] = {pitchC3, pitchD3, pitchE3, pitchF3, pitchG3, pitchA3, pitchB3};

```
> 1 votes

---
Tags: arduino-ide, midi
---


# Question
Title: Why can't I use 3V output of arduino pro mini?
I have an Arduino pro mini and I tested digital write of an pin and it is 3.2V and then I connected it to a 3V motor, but when I connected the motor to it, The voltage drops under 0.2 Volt, Can any one describe the science behind voltage drop ?

I know I've better use a transistor and separate the motor power but, what you should do when you have a single 3V power source? and I know there are some motor driver chips, but is it possible to keep it simple?

# Answer
> 1 votes
**NEVER** drive a motor directly from an Arduino IO pin. You **will** kill the Arduino.

It's not a question of voltage, it's a question of current, and that is where the transistor comes in. If you have a 3.3V Arduino (as it sounds like you have) then you *may* be able to drive the motor using the 3.3V output of the Arduino (VCC pin? Not sure with that model) and a transistor. That is the *simplest* arrangement.

simulate this circuit – Schematic created using CircuitLab

# Answer
> 0 votes
You can drive the motor from the same 3v supply that powers your Arduino (assuming the supply can deliver enough current for both). What you can't do is power the motor *through* the Arduino, neither from a pin, nor from its on-board voltage-regulator. And especially don't try to use a 5v Arduino's 3v pin to drive it. Their 3v regulators provide only a limited amount of current.

If you try to drive a motor through the Arduino and it needs too much current, you risk frying the Arduino. If you supply the motor from the same power supply but not through the Arduino, and the motor takes too much current, the worst that will happen is the supply voltage will fall and Arduino will shut down.

---
Tags: motor, arduino-pro-mini
---


# Question
Title: Problem with interrupts and 4x encoders on Nano 33 BLE
I have a Pololu 4x encoder and am trying to write some code to make it work on my Nano 33 BLE. (Interestingly enough, the issue preventing some pre-existing libraries from working for me is the same issue that I'm about to describe here...)

When I turn the motor shaft clockwise, these are the signals that I get (first bit in each pair is channel A, second bit channel B):

`11 -> 10 -> 11 -> 10 -> 11 -> 10`

Note how channel A's value never changes, and B's value toggles back and forth.

Likewise, for the counterclockwise direction:

`01 -> 11 -> 01 -> 11 -> 01 -> 11`

This is of course wrong, as the channels' values should be something like `00 -> 10 -> 11 -> 01 -> 00` as the shaft turns. As a matter of fact, that is exactly what I get when I run the *exact same code* on a regular Arduino Nano.

Does anyone know what's going on? Here's my code. AFAIK I'm not using interrupts incorrectly or anything, at least for the regular Nano.

```
#define PIN_A 2
#define PIN_B 3

volatile int val = 0;
volatile bool newVal = true;

void encoder() {
  int a = digitalRead(PIN_A);
  int b = digitalRead(PIN_B);
  val = ((a << 1) | b);
  newVal = true;
}

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

  pinMode(PIN_A, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_A), encoder, CHANGE);

  pinMode(PIN_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_B), encoder, CHANGE);
}

void loop() {
  if (newVal) {
    Serial.print(bool(val & 0b10));
    Serial.print(bool(val & 0b01));
    Serial.println();
    newVal = false;
  }
}

```

**EDIT:** After taking a look at the following diagram, it appears that the erroneous encoder patterns match those in which only rising edges are detected. So for some reason, `attachInterrupt()` is acting as if the `CHANGE` argument were `RISING` instead for the Nano BLE.

# Answer
> 0 votes
So it turns out the cause of the issue was that `attachInterrupt()`'s implementation in the nRF528x Mbed core does not properly support rising/falling edge detection as required for mode `CHANGE`. I've opened a pull request implementing the changes required and tested them with my encoder, and I can confirm that everything works properly now.

If you'd like to test the updated core yourself, you can follow the installation instructions from the repo's `README` or from this very well-written forum post.

# Answer
> 0 votes
Best practice would be to use a single interrupt for the encoder. BLE has a faster processor and your code is not frame-based so that just might affect it also. This code doesn't do exactly what your code did but it will use val to track position as a number. It can also be made a bit finer using CHANGE instead of RISING, but for debugging bare bones means less that can go wrong.

```
#define PIN_A 2
#define PIN_B 3

volatile int val = 0;
int oldVal;
//volatile bool newVal = true;

void encoder() {
  if(digitalRead(PIN_B)) ++val;
  else --val;
}

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

  pinMode(PIN_A, INPUT_PULLUP);
  pinMode(PIN_B, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(PIN_A), encoder, RISING);
}

void loop() {
  if (val != oldVal) {
    oldVal = val;
    Serial.println(oldVal);
  }
  delay(500);
}

```

---
Tags: rotary-encoder, arduino-nano-ble
---


title: SD card with arduino UNO

text:
# Question
Title: SD card with arduino UNO
I am trying to use a micro SD card in order to store data sent from an arduino UNO. My setup consists of:

The above components are connected as mentioned below: Pins 1 to 4 of the Digilent SD module are driven to the 3.3Voltage side of the logic level converter. Also the SD module is powered with 3.3Volts. The 4 signals (SS, MOSI, MISO, SCK) are then taken from the 5Volt side of the logic level converter and are driven to the arduino UNO pins 10, 11, 12 and 13 respectively. Also, all the components have a common ground. The card is formatted to FAT32 using the SD card Formatter from sdcard.org.

In the arduino, I upload the SdInfo sketch of the Sdfat library. The result I get is the following:

Let me know if I can provide any more info.

# Answer
> 0 votes
I doubt the SDHC card is supported.

I don't have the same card slot reader, however, mine only worked with 'old' SD cards, not SDHC, SDXC etc.

So try an old one to see if it works (at least you rule out this option).

---
Tags: arduino-uno, sd
---


# Question
Title: Can't upload sketch - avrdude: butterfly_recv(): programmer is not responding
I'm trying to upload a Blink example to run on a pro-micro (leonardo) but it is not working anymore (it was just working yesterday).

Steps to reproduce:

* Plug the device in USB port
* Open Blink example in Arduino IDE (version 1.8.8)
* Select the port and board accordingly to Arduino Leonardo
* Compile and try to upload it.

The code compile successfully but when uploading it just halts. The ide console displays:

> avrdude: error: programmer did not respond to command: exit bootloader
>
> Forcing reset using 1200bps open/close on port /dev/ttyACM0 PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} PORTS {/dev/ttyACM0, } / {/dev/ttyACM0, } =\> {} Uploading using selected port: /dev/ttyACM0 /home/fabio/Downloads/pacotes/arduino-1.8.8/hardware/tools/avr/bin/avrdude -C/home/fabio/Downloads/pacotes/arduino-1.8.8/hardware/tools/avr/etc/avrdude.conf -v -patmega32u4 -cavr109 -P/dev/ttyACM0 -b57600 -D -Uflash:w:/tmp/arduino\_build\_350609/Blink.ino.hex:i
>
> avrdude: Version 6.3-20171130 Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/ Copyright (c) 2007-2014 Joerg Wunsch
>
> ```
>      System wide configuration file is "/home/fabio/Downloads/pacotes/arduino-1.8.8/hardware/tools/avr/etc/avrdude.conf"
>      User configuration file is "/home/fabio/.avrduderc"
>      User configuration file does not exist or is not a regular file, skipping
>
>      Using Port                    : /dev/ttyACM0
>      Using Programmer              : avr109
>      Overriding Baud Rate          : 57600
>      AVR Part                      : ATmega32U4
>      Chip Erase delay              : 9000 us
>      PAGEL                         : PD7
>      BS2                           : PA0
>      RESET disposition             : dedicated
>      RETRY pulse                   : SCK
>      serial program mode           : yes
>      parallel program mode         : yes
>      Timeout                       : 200
>      StabDelay                     : 100
>      CmdexeDelay                   : 25
>      SyncLoops                     : 32
>      ByteDelay                     : 0
>      PollIndex                     : 3
>      PollValue                     : 0x53
>      Memory Detail                 :
>
>                               Block Poll               Page                       Polled
>        Memory Type Mode Delay Size  Indx Paged  Size   Size #Pages MinW  MaxW   ReadBack
>        ----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------
>        eeprom        65    20     4    0 no       1024    4      0  9000  9000 0x00 0x00
>        flash         65     6   128    0 yes     32768  128    256  4500  4500 0x00 0x00
>        lfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
>        hfuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
>        efuse          0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
>        lock           0     0     0    0 no          1    0      0  9000  9000 0x00 0x00
>        calibration    0     0     0    0 no          1    0      0     0     0 0x00 0x00
>        signature      0     0     0    0 no          3    0      0     0     0 0x00 0x00
>
>      Programmer Type : butterfly
>      Description     : Atmel AppNote AVR109 Boot Loader
>
> ```
>
> Connecting to programmer: .avrdude: butterfly\_recv(): programmer is not responding
>
> avrdude: butterfly\_recv(): programmer is not responding

A strange behavior I noticed is each time I plug the device again in the usb port different leds are light up, some times only RX, sometimes only TX and sometimes none (the power led is always on)

What could be happening here? Can it be the problem on the hardware?

# Answer
> 5 votes
I experienced the same frustrating issue for days. It was Ubuntu.

The fix was also so easy: sudo apt purge modemmanager

Until I discovered it, I suffered headache for days.

The auto upgrader may cause issues with this command. It can be solved with the following command:

sudo dpkg-reconfigure -plow unattended-upgrades

At the first prompt, choose not to download and install updates. Then reboot.

# Answer
> 3 votes
I have successfully solved this a year ago and I am trying to remember how I did it. So while it's fresh in my head this thing has to do with the bootloder.

The first and most obvious thing you can do is try to doubletap the reset and ground contact. Double tapping it will force the Arduino to reset and start in the bootloader for 8 seconds.

This is how I managed to install the driver for my pro-micro, it wouldn't install unless you did it when Arduino was in bootloader mode. But this strategy doesn't work for the code upload for some reason although many people claim it was the only thing that helped.

Another thing that could maybe help is clearing the Arduino's cache. When I was trying to compile a year ago, after many attempts I had to clear the pro-micro with another Arduino once in a while (you may need this later on). *\[thebusybee's note: I never heard about a cache in AVR micros. If a sketch is uploaded it will be flashed into the non-volatile memory overwriting all that was at its place before.\]*

Something else I remembered (if this is the case it would make things very problematic for me) is the USB cable. Again before my 1 year break I remembered that uploading the sketch for me only worked with 1 out of like 15 micro-USB cables I had (the one that's the shortest and thickest). That cable is broken now so I can't really check this unless I start researching microUSB cables right this instant.

Finally it may be the system. If nothing works try uploading the sketch from another preferably clean system.

Anyway, I hope you solve this because I am trying to solve the same issue.

Good luck

---
Tags: arduino-pro-micro
---


title: IR Remote with Arduino

text:
# Question
Title: IR Remote with Arduino
I want to build a remote with Arduino Nano. I have viewed many tutorials in the web, but I don't have the IR Receiver (TSOP1740). Is there any way to use Jjust an IR Led as the receiver?

# Answer
No, you can't use *just* an IR LED as the receiver. While it is true that an IR LED can also be an IR receiver the voltages it generates are really really small. So you would need an amplification circuit. On top of that the TSOP1740 includes a band-pass filter to isolate the carrier frequency of the transmitted signal from the background light, which you would *also* need to implement.

So yes, while you *could* use an IR LED as a receiver, you need a large amount of support circuitry with it (which takes expertise not relevant to this website) to get it to do anything useful.
> 2 votes

# Answer
You could make a remote without a receiver. It would require knowing what signals to send. The receiver is to essentially help in training your arduino by letting it detect the signal from an already working remote and then replay it on the LED.

You can't make a receiver with JUST an LED. (Majenko's got this one covered).
> 0 votes

---
Tags: arduino-nano, ir, remote-control
---


# Question
Title: Receiving garbage value when sending a Json object from Arduino Uno to NodeMCU using SoftwareSerial
I am trying to send a Json Object from Arduino UNO to NodeMCU using SoftwareSerial. I am using Arduino IDE. I am getting garbage value on Serial monitor of NodeMCU. Tried it with different garbage values, couldn't receive data from Arduino UNO. Below is the code. PLease help. Thank you in advance. I haven't made a common ground. I have referred this webpage here.

Arduino UNO code:

```
    #include <SoftwareSerial.h>
    #include <ArduinoJson.h>
    SoftwareSerial s(5,6);

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

    void loop() {
     StaticJsonBuffer<1000> jsonBuffer;
     JsonObject& root = jsonBuffer.createObject();
      root["data1"] = 100;
      root["data2"] = 200;
      if(s.available()>0)
      {
       root.printTo(s);
      }
    }

```

NodeMCU code:

```
    #include <SoftwareSerial.h>
    SoftwareSerial s(D6,D5);
    #include <ArduinoJson.h>

    void setup() {
      // Initialize Serial port
      Serial.begin(9600);
      s.begin(9600);
      while (!Serial) continue;

    }

    void loop() {
      StaticJsonBuffer<1000> jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(s);
      if (root == JsonObject::invalid())
        return;

      Serial.println("JSON received and parsed");
      root.prettyPrintTo(Serial);
      Serial.print("Data 1 ");
      Serial.println("");
      int data1=root["data1"];
      Serial.print(data1);
      Serial.print("   Data 2 ");
      int data2=root["data2"];
      Serial.print(data2);
      Serial.println("");
      Serial.println("---------------------xxxxx--------------------");

    }

```

# Answer
The problem with ArduinoJson.h is that it doesn't ensure robust and reliable transfer over UART serial.

Instead, you should use SerialTransfer.h to automatically packetize and parse your data for inter-Arduino communication without the headace.The library is installable through the Arduino IDE and includes many examples.

Here are the library's features:

> This library:
>
> * can be downloaded via the Arduino IDE's Libraries Manager (search "SerialTransfer.h")
> * works with "software-serial" libraries
> * is non blocking
> * uses packet delimiters
> * uses consistent overhead byte stuffing
> * uses CRC-8 (Polynomial 0x9B with lookup table)
> * allows the use of dynamically sized packets (packets can have payload lengths anywhere from 1 to 254 bytes)
> * can transfer bytes, ints, floats, and even structs!!

Example TX Arduino Sketch:

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  char buff[] = "hi";

  myTransfer.txObj(buff, sizeof(buff));
  myTransfer.sendData(sizeof(buff));
  delay(100);
}

```

Example RX Arduino Sketch:

```
#include "SerialTransfer.h"

SerialTransfer myTransfer;

void setup()
{
  Serial.begin(115200);
  Serial1.begin(115200);
  myTransfer.begin(Serial1);
}

void loop()
{
  if(myTransfer.available())
  {
    char buff[40];

    myTransfer.rxObj(buff, sizeof(buff));

    Serial.println("New Data: ");
    Serial.write(buff, sizeof(buff));
    Serial.println();
  }
  else if(myTransfer.status < 0)
  {
    Serial.print("ERROR: ");

    if(myTransfer.status == -1)
      Serial.println(F("CRC_ERROR"));
    else if(myTransfer.status == -2)
      Serial.println(F("PAYLOAD_ERROR"));
    else if(myTransfer.status == -3)
      Serial.println(F("STOP_BYTE_ERROR"));
  }
}

```
> 1 votes

---
Tags: arduino-uno, serial, nodemcu, softwareserial
---


title: Arduino SPI Multiplexer problems

text:
# Question
Title: Arduino SPI Multiplexer problems
I want to use the ADG731 32 ch multiplexer to read 32 potentiometers, I have wired everything and it works but it doesn't works as fast as I would want.

The problem is that If I turn a potentiometer between the range of 10-90% of the rotation, the analog reading is so slow, for example, if I have my POT at 0, and i turn it to 50%, it goes so slow until it reach the 512 value(like an hysteresis effect), BUT, if I turn the potentiometer back to 0 or up to 1023 it makes the reading as quick as I would expect.

So in resume it reads slowly the values except the edges values.

This is my code(I have set it to read only one potentiometer at pin S16 to test how the ADG731 works:

```
#include <SPI.h>

void loadDrain(void);
const int slaveSelectPin = 53;
void setup() {
  pinMode(slaveSelectPin, OUTPUT);
  SPI.begin();
  Serial.begin(9600);
}

void loop() {
  loadDrain();
}

void loadDrain(){
  SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE2));
  digitalWrite(slaveSelectPin, LOW);
  SPI.transfer(00001111);
  digitalWrite(slaveSelectPin, HIGH);
  SPI.endTransaction();
  Serial.println(analogRead(A0) >> 3);
}

```

# Answer
Take a deep look into the library you are using to read the POT. Most HW and / or SW will take many readings & average them to remove the randomness and improve the accuracy of the ADC HW. It could be that your setup is so noisy that the SW is compensating by taking even more readings to average. Hats off the the SW developer who had the foresight to adapt the code to noisier situations. If true, and you think that too much automation, remember you are using the Arduino platform where the libraries are designed to make things simple by abstracting (hiding) the hardware details.
> 1 votes

# Answer
Some things look odd:

Why do this every time? You only need to set these up one time in setup():

```
SPI.beginTransaction(SPISettings(30000000, MSBFIRST, SPI_MODE2));

```

Most 16 MHz Arduinos, including the Mega you appear to be using, won't do 3 MHz, choices are 8 MHz, 4,MHz, 2 MHz, 1 MHz and 3 or 4 more slower speeds.

The chip seems to support higher speeds, 8 MHz should work:

> fSCLK 30 MHz max SCLK Cycle Frequency

So run it faster to same on time.

Why take a 10-bit reading and shift it down to 7?

```
Serial.println(analogRead(A0) >> 3);

```

You could speed up the reads by doing an 8-bit read instead of 10-bit, and use a faster Serial speed, up to 115200, to send the results out.

Instead of digitalWrite() to control the slaveSelect pin, you could use direct port manipulation to toggle that pin. You can write a 1 to the Input port to toggle the output bit. From the Atmega2560 datasheet:

> Toggling the Pin
>
> Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn. Note that the SBI instruction can be used to toggle one single bit in a port.
> 0 votes

# Answer
You can modify beginT and endT // test SPI slave n=1
SPI.beginTransaction(1, SPISettings(30000000, MSBFIRST, SPI\_MODE2)); SPI.transfer(00001111); SPI.endTransaction(1);
> 0 votes

---
Tags: arduino-mega, spi, multiplexer
---


# Question
Title: What does []() argument in function mean?
I am working in ESP8266 AsyncWebserver library and have been using this `[](parameter)` as an argument to some functions as shown below but does not really know what it means. Being a neophyte I am curious to know what does this convention means, its functionalities and how to use it. Hopefully experts here would help me with this.

```
server.on("/page",HTTP_GET,[](AsyncWebServerRequest * request){
    some code....;
    request->getParam("Param1")->value();
});

```

# Answer
That is called a *lambda expression* and it's a way of including the content of a function as a parameter anonymously instead of writing an actual function and using the name of it.

It's shorthand for:

```
void myCallback(AsyncWebServerRequest * request) {
    // some code....;
    request->getParam("Param1")->value();
}

// ...

server.on("/page", HTTP_GET, myCallback);

```

It does have a few benefits over traditional functions at the expense of readability, such as the ability to "capture" local variables from the surrounding scope.
> 5 votes

---
Tags: esp8266, c++, web-server, functions
---


# Question
Title: USB control panel with endless turn knobs
I understand that some arduinos are capable of presenting themselves as a USB HID device to a PC.

I would like to use one to build a custom input controller that lets me read maybe 8 or so turn knobs that can infinitely turn left and right.

I am new to Arduino, but have cross-compiled avr binaries before.

Which arduino would be a good choice for this? And any additional parts that would help?

The end product would look like a MIDI mix panel, but it shouldn’t talk MIDI, just USB HID (to a linux PC.)

Note: there is an expensive, and out of stock, device that is similar to what I have in mind called MIDI Fighter Twister, pictured below, to get an idea.

# Answer
> 1 votes
Options for the Arduino you have:

* Get an Arduino supporting HID drivers (e.g. 32u4 based boards, Due /Zero/ Arduino Leonardo/ Micro or Pro Micro/ M0)
* You use this library it supports UNO/MEGA/Leonardo/(Pro)Micro/ any 8u2/16u2/at90usb8/162/32u2/32u4 compatible boards and some more

Then you have to "just" code the communication between your programm and the HID driver -\> pretty standard serial/usb stuff.
The parts (knobs) you seek could be rotary encoders, which have no fixed zero point, endless rotation and need 2 input pins per encoder (except GND or optional push function). The signals a rotary encoder produces (and what can be handled by libraries) are based on a 2-bit gray code available on 2 digital data signal lines. So when choosing whatever Arduino make sure you have enough (usable) I/O ports for the number of encoders and possible additional parts (status led/s or similar, I2C LCD display)

---
Tags: usb, input, hid
---


# Question
Title: Multiplication operator with or without braces
I have written a simple calculator program for an LCD keypad shield. It works fine except for the multiplication case. It gives me zero. However, I have noticed that when I enclose the expression num1 * num2 in parenthesis it does work. Why is that so?

```
#include <LiquidCrystal.h>

LiquidCrystal lcd (8, 9, 4, 5, 6, 7);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {

  float ans = 0;

  lcd.print("Starting Calc");
  delay(500);

  lcd.clear();
  lcd.print("Enter 1st Num");
  while (Serial.available() == 0) {}
  float num1 = Serial.parseFloat();

  lcd.clear();
  lcd.print("Enter 2nd Num");
  while (Serial.available () == 0) {}
  float num2 = Serial.parseFloat();

  lcd.clear();
  lcd.print("Enter Operator");
  lcd.setCursor(0, 1);
  lcd.print(" R+, U*, D/, L- ");
  int val = analogRead(A0);

  while (val > 1000) {
    val = analogRead(A0);
  }

  if (val == 0) { // addition
    ans = num1 + num2;
  }

  if (val >= 97 && val <= 98) { // multiplication
    ans = num1 * num2;
  }

  if (val >= 253 && val <= 254) { // division
    ans = num1 / num2;
  }

  if (val >= 407 && val <= 408) { // subtraction
    ans = num1 - num2;
  }

    lcd.clear();
    lcd.print("Answer is = ");
    lcd.print(ans);
    delay(2000);
}

```

---

## Modified Code

```
#include <LiquidCrystal.h>

LiquidCrystal lcd (8, 9, 4, 5, 6, 7);

void setup() {
  Serial.begin(9600);
  lcd.begin(16, 2);
  lcd.clear();
}

void loop() {

  float ans = 0.0;

  lcd.print("Starting Calc");
  delay(500);

  lcd.clear();
  lcd.print("Enter 1st Num");
  while (Serial.available() == 0) {}
  float num1 = Serial.parseFloat();

  lcd.clear();
  lcd.print("Enter 2nd Num");
  while (Serial.available () == 0) {}
  float num2 = Serial.parseFloat();

  lcd.clear();
  lcd.print("Enter Operator");
  lcd.setCursor(0, 1);
  lcd.print(" R+, U*, D/, L- ");

  // here we split our logic.. first repeatedly read input value until valid operator read
  // secondly we perform the arithmetic operation accordingly

  char input = ' '; // space = no operator read so far
  int val;

  do {
    val = analogRead(A0);
    // see how if statements are written concisely for readability
    // if only one statement after condition you can skip curly brackets
    if (val == 0) input = '+';
    if (val >= 97 && val <= 98) input = '*';
    if (val >= 253 && val <= 254) input = '/';
    if (val >= 407 && val <= 408) input = '-';
  } while (input == ' ');

  Serial.println(input);
  Serial.println(num1);
  Serial.println(num2);
  delay(1000);

  // perform arithmetic operation
    switch (val) { // not written in a standard way but very readable
      case '+': ans = num1 + num2; break;
      case '-': ans = num1 - num2; break;
      case '*': ans = num1 * num2; break;
      case '/': ans = num1 / num2; break;
    }

  lcd.clear();
  lcd.print("Answer = ");
  lcd.print(ans);
  delay(2000);
}

```

# Answer
> 0 votes
The parentheses should definitely make no difference. My guess is that what you saw was just a coincidence. The analog ranges you have defined are extremely narrow. Any instability in the circuit can throw your readings out of the expected ranges. If you get a reading that does not fit in any of those ranges, none of the `if` conditions will evaluate to `true`, and you end up with the result being zero, as this is how you initialized the variable `ans`.

I suggest two changes to your program:

1. Make the ranges wider
2. Repeatedly read the analog input *until* you get a valid reading.

To illustrate the second item, here is a code snippet that splits the logic of you `if` chain in two parts: first read the operator (repeatedly until we get a valid reading), then perform the operation:

```
// Read the operator.
char op = ' ';  // space = no operator read so far
do {
    int val = analogRead(A0);
    if (val == 0) op = '+';
    if (val >= 97 && val <= 98) op = '*';
    if (val >= 253 && val <= 254) op = '/';
    if (val >= 407 && val <= 408) op = '-';
} while (op == ' ');

// Perform the operation.
switch (op) {
    case '+': ans = num1 + num2; break;
    case '*': ans = num1 * num2; break;
    case '/': ans = num1 / num2; break;
    case '-': ans = num1 - num2; break;
}

```

---
Tags: arduino-uno
---


# Question
Title: Serial.println using too much memory (not Strings)
I want to feed thousands of analog vibration sensor readings into an array as fast as possible, and then analyze them. Here is my sketch:

```
const int pSensor1 = A0;
const int aSize=10000;

int a[aSize];

void setup()
{
  pinMode(pSensor1, INPUT);
  Serial.begin(9600);
}

void loop()
{
  for (int i = 0; i < aSize; i++) a[i] = analogRead(pSensor1);

  int RMS = 0;
  for (int i = 0; i < aSize; i++) RMS += pow(a[i], 2);
  RMS = sqrt(RMS/aSize);

  Serial.println("Hello");
}

```

This compiles and runs fine. My problem arises when I try to change the last line to:

`Serial.println(RMS);`

I get the error:

> Arduino: 1.8.12 (Windows 10), Board: "Arduino Nano, ATmega328P"
>
> Sketch uses 3270 bytes (10%) of program storage space. Maximum is 30720 bytes. Global variables use 20188 bytes (985%) of dynamic memory, leaving -18140 bytes for local variables. Maximum is 2048 bytes. data section exceeds available space in board Not enough memory; see http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing your footprint. Error compiling for board Arduino Nano.

Why does attempting to Serial print a single floating point variable use 985% of dynamic memory?

# Answer
Probably if you don't print them then the compiler sees that array is never used for anything so it gets optimized away. It sees that it is useless code that doesn't affect anything and simply removes it. Once you print it then it actually has to be included in the compiled code.

Think about this. The Arduino you are using has 2000 bytes of memory. One int takes 2 bytes. You want 10,000 of them. That's 20,000 bytes of memory. 20,000 bytes will never ever fit into 2,000 bytes. You need to choose a more reasonable number of samples.
> 2 votes

---
Tags: arduino-nano, memory-usage
---


# Question
Title: How to store firmware configuration or image in source-control?
I'm writing an Arduino application in C/C++ and I'm storing my source code in Github.

However, to make my code runnable, I have had to install multiple libraries through the Arduino desktop tool like this:

And I have had to update the firmware and certificates through the Arduino desktop tool like this:

How can I store these firmware updates, library changes and certificates in source control? Is there a binary image I can download and check in? Better yet, is there some plain-text source file that I can check-in to derive such a binary?

# Answer
> 1 votes
For libraries only add comment next to #include with version number and author's name if the library is in Library Manager or the download location if it is not in Manager.

Example:

```
#include <MemoryFree.h> // https://github.com/mpflaga/Arduino-MemoryFree
#include <Ethernet.h> // Ethernet 2.00

```

Put NINA firmware version in some comment at the top of the main sketch file. The firmware is part of the Arduino boards package so no need to store it in your repo. If you modified the firmware, publish source code in your fork of the official repository and there you can then release the binary too.

Put public certificate keys and similar files in sketch folder in subfolder called `extras` or `data`.

And write a README file for your repository.

---
Tags: firmware
---


# Question
Title: Can I connect 220V AC supply to Node MCU (or any arduino)pin D1 and D3 while node MCDU is power off?
Can I connect 220V AC supply to node MCU pin D1 and D3 while node MCDU is power off?

# Answer
No, never! 220V is way way way too much for a microcontroller. The Uno runs on 5V, the ESP8266 on 3.3V. You should never connect any more voltage than that to the microcontroller. Also you must not connect a negative voltage to the microcontroller pins.

Besides the voltage difference: You should also not connect a voltage to the pins of a microcontroller, while the microcontroller itself is turned off (meaning that it does not have the necessary supply voltage). In that case a parasite current would run through the clamping diodes, which powers the microncontroller, until the diodes get blown.

---

As an **important** side note: **Don't do anything with mains power (like 220V AC), until you really know, what you are doing!!! One error and it can kill you !!!**
> 4 votes

---
Tags: arduino-uno, esp8266, nodemcu
---


title: Pushbutton and switch case

text:
# Question
Title: Pushbutton and switch case
I am developing a project for my college.

PROJECT OUTLINE: There are 3 sensors (Temp., Accelerometer & Humidity) will read the respective parameters continuously. in between if I press 'PushButton1' for 2 seconds the Arduino must enter into programming mode.

The programming mode has 6 Switch cases. Each case gets selected one after one on the even of 'PushButton1' gets pressed for short time.

Also if I press 'PushButton1' again for 2 seconds in Programming mode the Arduino should come out of the programming mode.

PROBLEM: In my current sketch I have to press 'PushButton1' for 2 seconds in Programming Mode for 2 seconds to change the case. Also I don't understand how to get out of the Switch Case loop.

The sketch is attached with this topic.

```
const int btn = 2;
const int ledPin =  13;
int selector = 0;
boolean  volatile wait = false;
const unsigned long event=2000;
unsigned long a=0;
unsigned long b=0;
unsigned long c=0;
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(btn, INPUT);
attachInterrupt(digitalPinToInterrupt(btn),decoder,CHANGE);
}

void loop()
{
  while(wait) {  }
  if (digitalRead(btn) == LOW) {
    a = millis();
  }
  else
  {
    b = millis();
    c=b-a;
    Serial.println(c);
        if (c>=event)
            {
              doSwitchStatement();
              selector++;
              if (selector >6)
                  {
                  selector = 0;
                  delay(500);
                  }
            }
  }
  wait = true;
  interrupts();

}

void decoder()
{
  noInterrupts();
  wait = false;
}

void doSwitchStatement()
{
  switch(selector)
  {
  case 0:
    Serial.println("Case 0");
    break;

  case 1:
    Serial.println("Case 1");
    break;

  case 2:
   Serial.println("Case 2");
    break;

  case 3:
   Serial.println("Case 3");
     break;

  case 4:
   Serial.println("Case 4");
    break;

  case 5:
  Serial.println("Case 5");
    break;

  case 6:
  Serial.println("Case 6");
    break;

  }
}

```

# Answer
> 0 votes
I would do it as a simple state without the blocking while define two bools

```
bool buttonPress = false;
bool inMenu = false;

```

and add it to the loop.
To differentiate between different press lengths you need to define them. There is nothing like an "automatic" short press recognition. Also use variables which are "speaking" making it easier to read code for others.

```
const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;
// debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

```

The program below does what you want (tested on my uno test lab).
As Edgar Bonet commented before you should also debounce the button (look it up in WiKi) to exclude unwanted effects The times I use are practical on my hardware, so you could play around by looking at the serial monitor.

```
const int btn = 2;
const int ledPin =  13;
int selector = 0;
const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;  // debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

bool buttonPress = false;
bool inMenu = false;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(btn, INPUT);
  }

void loop() {
  if (digitalRead(btn) == LOW && !buttonPress ) {
    buttonPressStart = millis();
    buttonPress = true;
  }
  // The routine is only triggered if a previous pressing took place, otherwise it's ignored
  else if (digitalRead(btn) == HIGH && buttonPress) {
    if (millis() - buttonPressStart > buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Long press: ");
      Serial.println(millis() - buttonPressStart);
      buttonPress = false;
      inMenu = false;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && !inMenu) {
      Serial.print("First short press ");
      inMenu = true;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Short press: ");
      Serial.println(millis() - buttonPressStart);
      doSwitchStatement();
      selector++;
      if (selector > 6) {
        selector = 0;
        delay(500);
      }
      buttonPress = false;
    }
  }
  // Here you could do other stuff as it is non blocking
}
doSwitchStatement(){...}// Stays the same as yours

```

Look at the code used as it is non blocking (of course there is room for improvement) but as a starter for your further experiments ...

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


title: Put Arduino in DFU mode (no RST pin)

text:
# Question
Title: Put Arduino in DFU mode (no RST pin)
The instructions to put the Arduino into DFU say I should shortcut briefly the 2 leftmost ICSP headers next to the USB port.  But my board does not have them. Does anybody know what are the right headers or if it is at all possible to set my board into DFU mode?

# Answer
It has a CH340G usb serial adapter, which cannot be reprogrammed and has no DFU mode.

If you are looking for DFU mode because it's not detecting correctly and you think it's because the 16u2 isn't programmed correctly, the problem is probably that you need to install the CH340G drivers, not the normal Arduino drivers.

If you are looking for DFU mode for some project that requires custom firmware on the CH340G, that board is not usable for that project, you will need to get a faithful clone of the Uno, which has the 16u2, not the CH340G based ones
**EDIT**
If you want to use your Arduino as a HID device you need the DFU mode
If you use this library which supports UNO/MEGA/Leonardo/(Pro)Micro/ any 8u2/16u2/at90usb8/162/32u2/32u4 compatible board and some more **BUT you need an 16u2 chip**
> 1 votes

# Answer
This board doesn't use as USB adapter an ATMega16u2 with Arduino firmware. It uses a simple USB chip CH340. So you can't put it in DFU mode to upload a firmware.
> 1 votes

---
Tags: pins
---


# Question
Title: What does a tilde (~) mean as annotation for a data pin?
When I examine the datasheet for the Arduino Micro (couldn't find the Pro Micro on their site, btw) then I see some data pins annotated with a ~ character, and some are not.

For instance, D9 has a ~ annotation, D8 does not.

What does this annotation mean?

# Answer
It means the pin can be a PWM output for use with `analogWrite()`.
> 5 votes

---
Tags: pins, arduino-micro, arduino-pro-micro
---


# Question
Title: DHT11 and Liquidcrystal setting cursor issue
```
lcd_key = read_LCD_buttons();
float temp = dht.readTemperature();
delay(1000);
// lcd.setCursor(0,0);

if(temp < 0) {
    lcd.print(temp);
}

if(temp >= 0.00 || temp <= 5.00) {
    lcd.setCursor(0,6);
    lcd.print(temp);
    delay(100);
}

```

Here I got simple code about reading temperature from DHT sensor and lcd but when I raise or lower the DHT's temperature the lcd's cursor always printing my data from 0,0.

I want that when the temperature between 0-5 celcius it shall write data on 0,6 in lcd screen but this code not working.

Thank you for answers.

# Answer
I have a feeling you may be using invalid coordinates.

`0, 6` means *Column 0, Row 6*, but most LCDs don't have 6 rows. Instead I think you want `6, 0` for *Column 6, row 0*.
> 1 votes

# Answer
I guess it because you use

```
if(temp >= 0.00 || temp <= 5.00){ // writes over 0 OR under 5 which will always be true for all values measured

```

and not

```
if(temp >= 0.00 && temp <= 5.00){   // writes over 0 AND under 5 which you want

```
> 1 votes

---
Tags: lcd, atmega2560
---


# Question
Title: Pushbutton and switch case follow up question
PROBLEM STATEMENT:

1. A circuit is measuring various parameters (Temperature, Humidity, etc.) through sensors connected to it continuously.
2. When a Push Button is Pressed and Hold for 2 seconds in between the Arduino should enter into Setup mode.(I have used IF loop and millis() function to achieve this )
3. In Setup mode there are 6 screens which will appear one after one.
4. Once Arduino enters into Setup mode Switch case 0 (screen1) should appear (I have used serial monitor for the same).
5. Now if I press the same push button and released within a moment the next Switch case 1 (screen2) should appear.
6. Step 5 will be repeated till Switch case 5 (screen6).
7. After Switch case 5 the loop rolls over to Switch case 0 (SCREEN1) then Switch case 1, Switch case 2, so on.
8. If in between above Switch Case loop Push Button is Presses and Hold for 2 seconds the Switch case loop must get terminated and the Arduino should go back to MAIN LOOP() where it is measuring the sensor parameter.
9. Again if the push button is Pressed and Hold for 2 seconds in between sensing process the Arduino should enter into Setup mode.

CONSIDERATIONS:

1. Push Button is connected to Pin2 of Arduino (ACTIVE LOW)
2. The input at Pin2 is considered as interrupt so that Arduino provides service to any moment of the time.
3. Arduino serial monitor is used to demo the Screen1-Screen6 as output.
4. 0.1uf Capacitor is used across the Push Button for debounce considerations. And 10K, 0.25W resistor is connected from VCC to Pin no.2
5. The code for sensing parameters (Temperature, Humidity, etc.) is yet to be written.

ACHIEVEMENT: Upto Point No. 7 of PROBLEM STATEMENT the code is working fine.

BUG: If I press Push Button for 2 seconds in SWITCH CASE loop, Arduino is going out of the SWITCH CASE and going into MAIN LOOP() but again coming back to SWITCH CASE() loop. It should ask again to press Push Button for 2 Seconds to enter into Setup Mode.

```
const int btn = 2;
const int ledPin =  13;
int selector = 0;
boolean  volatile wait = false;
const unsigned long event=2000;
unsigned long previous1=0;
unsigned long current1=0;
unsigned long sum1=0;
unsigned long previous2=0;
unsigned long current2=0;
unsigned long sum2=0;
bool buttonPress = false;
void setup()
{
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
pinMode(btn, INPUT);
attachInterrupt(digitalPinToInterrupt(btn),decoder,CHANGE);
}

void loop()
{
  if (digitalRead(btn) ==LOW && !buttonPress)
  {
    previous1 = millis();
    buttonPress = true;
  }
  else if (digitalRead(btn) == HIGH && buttonPress)
  {
    current1 = millis();
    sum1=current1-previous1;
    Serial.println(sum1);
    Serial.println("SUM1");
    if (sum1>=event)

       {  BREAK1:
          doSwitchCase();
          selector++;
          goto BREAK1;
          if (selector >6)
              {
                  selector = 0;
                  delay(500);
              }
        }
        buttonPress = false;
  }
  wait = true;
  interrupts();

}

void decoder()
{
 noInterrupts();
 wait = false;
}

void doSwitchCase()
{
  switch(selector)
  {
  case 0:
    Serial.println("SCREEN1");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
    break;

  case 1:
    Serial.println("SCREEN2");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
    break;

  case 2:
   Serial.println("SCREEN3");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
   break;

  case 3:
   Serial.println("SCREEN4");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
   break;

  case 4:
   Serial.println("SCREEN5");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
   break;

  case 5:
  Serial.println("SCREEN6");
    while (digitalRead(btn)!=LOW) ;
    previous2 =millis();
    while (digitalRead(btn)!=HIGH) ;
    current2=millis();
    sum2=current2-previous2;
        if(sum2>=event)
        {
         Serial.println(sum2);
         loop();
        }
  break;
  }
}

```

# Answer
One note before **NEVER** use goto in C++ its bad style and makes in an object oriented language to 99.9% no sense. To enter the switch case after a2 second press you have just to enter one statement t omy original proposal.I did not read your code as it gets unreadable the more functionality you want to add. Think about refactoring it or you will run out of luck to get help (as nobody tortues himself with caotic code of others:

```
const int btn = 2;
const int ledPin =  13;
int selector = 0;
const unsigned long buttonPressLong = 2000;  // 2 seconds
const unsigned long buttonPressShort = 250;  // 0.25 secondis feasable
const unsigned long buttonPressDebounce = 50;  // debouncing for too short presse Thanks Edgar Bonet
unsigned long buttonPressStart = 0;

bool buttonPress = false;
bool inMenu = false;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(btn, INPUT);
  }

void loop() {
  if (digitalRead(btn) == LOW && !buttonPress ) {
    buttonPressStart = millis();
    buttonPress = true;
  }
  // The routine is only triggered if a previous pressing took place, otherwise it's ignored
  else if (digitalRead(btn) == HIGH && buttonPress) {
    if (millis() - buttonPressStart > buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Long press: ");
      Serial.println(millis() - buttonPressStart);
      buttonPress = false;
      inMenu = false;
    }
    if (millis() - buttonPressStart < buttonPressLong && millis() - buttonPressStart > buttonPressDebounce && !inMenu) {    // HERE IS A CHANGE
      Serial.print("First long press ");    // HERE IS A CHANGE
      inMenu = true;
    }
    if (millis() - buttonPressStart < buttonPressShort && millis() - buttonPressStart > buttonPressDebounce && inMenu) {
      Serial.print("Short press: ");
      Serial.println(millis() - buttonPressStart);
      doSwitchStatement();
      selector++;
      if (selector > 6) {
        selector = 0;
        delay(500);
      }
      buttonPress = false;
    }
  }
  // Here you could do other stuff as it is non blocking
}
doSwitchStatement(){...}// Stays the same as yours

```

I just changed 1 statement (and 1 debug msg) to achieve what you want see // HERE IS A CHANGE
> 1 votes

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


# Question
Title: How to find the time of any point on the graph on an Arduino serial plotter or Processing software?
I am plotting the graph of some sensor values on my Arduino serial plotter which looks something like this -

But what I want to do is hover over any point on the graph and display the time at that point. Is there any way to do that, if not with Arduino serial plotter, with Processing? Or any other tool is fine too. Thanks.

# Answer
> 0 votes
The Arduino Serial Plotter is not meant for this. It just directly draws, what you send. You can solve this in processing, by calculating the time from the number of the current sample (which is what you see on the x axis in your plot) via the used sampling rate.

---
Tags: arduino-ide, sensors, arduino-pro-mini, processing-lang
---