message:
Global Variable not updating…

I'm building a small project to maintain a copper plating tank's temperature and filter pump duty cycle. I'm using the Adafruit Feather platform to hold an 8 segment matrix coupled with a Teensy 3.2 (on a Feather shield) to calculate and display temp. There is a 10K Pot on A0 and an 8 segment NeoPixel Strip to set and display pump duty cycle from 1 to 8 corresponding to .125*hour and 100% on. There is also a push and hold set switch to operate temperature target point setting using the same pot.

Things that work: Almost Everything!
Thing that doesn't work:

Changing the Duty Cycle knob (which changes the duty cycle global variable) after turning the unit on doesn't seem to change the on/off times other than to successfully change the NeoPixel display. If the unit is turned on at a particular duty cycle, the program will run that duty cycle successfully. While running, if I change the duty Cycle to 8, I don't get a "100% On". In other words the change in the duty cycle variable doesn't seem to change the on time and off time variables in the code while running.

Q: What do I need to do to make the duty cycle setting work on the fly?

Oh... That Volatile Float declaration was my last desperate attempt, Please ignore / forgive. ;-)

Hopefully the fix is as simple as the code. ;-) I just don't see it and my (perhaps flawed) understanding of global variables is hit a wall.

Any help will be much appreciated. Thanks.

Jeff

Code:

```

/***************************************************
  Copper Plating Tank Control - v1.1
  by Jeff W. Parisse - July 7st, 2021
  www.coppercholla.com

  This program runs a programmable interval timer for chemical pump
  duty cycle and a programmable temperature setting and heating control
  for maintaining plating solution temperature.

  Processor: PJRC Teensy 3.2
  Additional Libraries: Adafruit Industries LLC
  Temperature Sensor: Adafruit MAX31865 w/P1000 Platinum Wire Probe
  Pin Outs:
    Setting Knob: Pin A0
    Matrix Display: Feather Matrix I2C 0x70
    Neopixels: Pin 5
    MAX31865: CLK Blue
    MAX31865: SDO Yellow
    MAX31865: SDI White
    MAX31865: CS Pin 6 Green
    Temp Set Switch: Pin 8
    Chemical Pump: Pin 9
    Tank Heater: Pin 10

 ****************************************************/

#include <Adafruit_MAX31865.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include <Adafruit_NeoPixel.h>

#define knobPin A0
#define ledPin 5
#define csPin 6
#define switchPin 8
#define pumpPin 9
#define heaterPin 10
#define ledCount 8
#define sampleNum 4
#define RREF      4296.0
#define RNOMINAL  1000.0

Adafruit_MAX31865 thermo = Adafruit_MAX31865(csPin);
Adafruit_7segment matrix = Adafruit_7segment();
Adafruit_NeoPixel strip(ledCount, ledPin, NEO_GRB + NEO_KHZ800);

float targetTemp = 77.0;                // Starting Value
float readTemp = 0;
float toleranceTemp = 0.25;
float tempSum = 0;
float cTemp = 0;
float fTemp = 0;
volatile float dutyCycle = 4;
unsigned long previousTime = 0;
unsigned long oneHour = 3600000;       // 1 Hour in Milliseconds
unsigned long timeOn = 450000;         // 7.5 Minutes in Milliseconds
unsigned long pumpInterval = timeOn;
boolean pumpState = true;

void setup() {
  thermo.begin(MAX31865_3WIRE);;
  matrix.begin(0x70);
  strip.begin();
  strip.show();
  pinMode(csPin, OUTPUT);
  pinMode(heaterPin, OUTPUT);
  pinMode(pumpPin, OUTPUT);
  pinMode(switchPin, INPUT_PULLUP);
  digitalWrite(csPin, LOW);
  digitalWrite(heaterPin, LOW);
  digitalWrite(pumpPin, LOW);
}

void loop() {
  // Read Set Switch
  int setSwitch = (digitalRead(switchPin));
  while (setSwitch == LOW) {
    int readKnob = analogRead(knobPin);
    targetTemp = map(readKnob, 1, 1023, 67, 87);
    matrix.print(targetTemp, 1);
    matrix.writeDisplay();
    setSwitch = (digitalRead(switchPin));
  }

  // Read, Convert, and Display Temp
  tempSum = 0;
  for (int i = 1; i <= sampleNum; i++) {
    readTemp = thermo.temperature(RNOMINAL, RREF);
    tempSum = tempSum + readTemp;
  }
  cTemp = tempSum / sampleNum;
  fTemp = (cTemp * 1.8) + 32;
  matrix.print(fTemp, 1);
  matrix.writeDisplay();

  // Heater Logic
  if (fTemp < targetTemp - toleranceTemp) {
    digitalWrite(heaterPin, HIGH);
  }
  else if (fTemp > targetTemp + toleranceTemp) {
    digitalWrite(heaterPin, LOW);
  }

  // Read and Display Duty Cycle
  int readKnob = analogRead(knobPin);
  dutyCycle = map(readKnob, 1, 1023, 1, 8);
  for (int i = 0; i <= ledCount; i++) {
    strip.setPixelColor(i, 0, 0, 0);
  }
  strip.show();
  for (int i = 0; i <= dutyCycle - 1; i++) {
    strip.setPixelColor(i, 0, 0, 20);
  }
  strip.show();

  // Pump Timer
  digitalWrite(pumpPin, pumpState);
  unsigned long timeOn = ((dutyCycle / 8UL) * oneHour);
  unsigned long timeOff = (oneHour - timeOn);
  unsigned long currentTime = millis();
  if (currentTime - previousTime >= pumpInterval) {
    if (pumpState) {
      pumpInterval = timeOff;
    }
    else {
      pumpInterval = timeOn;
    }
    pumpState = !(pumpState);
    previousTime = currentTime;
  }
}

```

body:
I do not really understand what may be the cause of your problem, but I
have identified two issues that could potentially be related.

You have:

> ```c++
> dutyCycle = map(readKnob, 1, 1023, 1, 8);
> ```

Because of some rounding issues in the Arduino `map()` function, this
may not work as you expect: the output will be 8 only if the input
reaches 1023. If `readKnob` is 1022, `dutyCycle` will be 7. This may
explain why you never see the pump being constantly on.

The way `map()` works makes most sense if you think in terms of
_half-open_ intervals, open on the right. If you write:

```c++
dutyCycle = map(readKnob, 0, 1024, 1, 9);
```

you will get a perfect mapping from [0, 1024) to [1, 9). Perfect in the
sense that there will be exactly 128 input values mapped to each output
value:

    [  0, 128) → 1
    [128, 256) → 2
    [256, 384) → 3
    ...

And later:

> ```c++
> for (int i = 0; i <= ledCount; i++) {
>     strip.setPixelColor(i, 0, 0, 0);
> }
> ```

The strip has `ledCount` pixels, numbered 0 to `ledCount-1`. This loop
will set the color of pixels 0 through `ledCount` inclusive. The last
iteration goes beyond the end of the strip, and it is most likely
corrupting memory, i.e. overwriting whatever data happens to sit right
after the memory area used for the strip. If this is overwriting some
variable related to the duty cycle, that may explain the weird behavior
you experience.


sender: user

message:
Can I get the hex file from an Arduino without the .ino code

I have a CNC router table that came into my local makerspace. The board looks like it has some standard parts, but also has some parts I don't recognize. At the heart of it is an Arduino Uno. I would like to get the code from the UNO, as a back up. I will have to do testing on this board, but I don't want to overwrite something I don't have a back up of.

is there a way to get the firmware off of the arduino, without having the ino files that generated it?

(This is a standard function on many other platforms such as PIC, I just don't know how to do it in Arudino. I am assuming the functionality also exists.)

sender: assistant

body:
Cool I got it using avrdude.
$ `avrdude -c arduino -P /dev/ttyUSB0 -b 9600 -p m328p -U  flash:r:CNCArdunio.hex:i`

    > -c the platform (basically)
    > -P the port where your harware is.
    > -b the baudrate.
    > -p the chip architecture.
    > -U momory type flash  :r option to read to file  :i option to format into Intel HEX.

caveats.Upon closer inspection this is either a very early model UNO, or a cheap clone. It comes up at /dev/ttyUSB0, and required that I press the reset button shortly before sending the avrdude command, else it resulted in

    avrdude: stk500_recv(): programmer is not responding
    avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00


message:
Push button unexpected increment/decrement. I'm using attachInterrupt

I'm new to Arduino and need assistance from knowledgeable people.
I'm having a problem with my code, which allows the user to increase or decrease the number by pressing buttons. From time to time, the number does not change by one, but by two or three. This occurs on a sporadic basis. This is known as "bouncing." I googled "attachInterrupt debounce" in vain, but I couldn't find a suitable solution. My code is here.
```
int digit_state = 0;
void increment(void){
  digit_state = digit_state + 1;
  }
void decrement(void){
  digit_state = digit_state - 1;
  }
String user_input = "";
String password = "3452";
int enterbutton = 11;
int increment_button = 2;
int decrement_button = 3;
int counter = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(enterbutton,INPUT);
  attachInterrupt(digitalPinToInterrupt(increment_button),increment,FALLING);
  attachInterrupt(digitalPinToInterrupt(decrement_button),decrement,FALLING);
}

void loop() {
  // put your main code here, to run repeatedly:
  lastButtonState = reading;
  while(counter<=3){
    delay(500);
    Serial.println(digit_state);
    if(digitalRead(enterbutton)==LOW){
      user_input = user_input + digit_state;
      Serial.println("Saved input so far is "+user_input);
      if(user_input == password){
        Serial.println("検証できた");
      }
      delay(500);
      digit_state = 0;
      counter++;
  }
}
}

```
As the user presses, I need to stop it from bouncing and get an accurate password all the time.

body:
First: It is not necessary to use interrupts for buttons, because when humans press buttons they will be at least actived for about 100ms, which is very slow for a microcontroller. You would just need to rewrite your code to be non-blocking (for example by ditching all `delay()` calls and instead use `millis()` like in the `BlinkWithoutDelay` example, that comes with the Arduino IDE). Then you can also use existing libraries for debouncing like [Bounce2][1].

---

A very simple approach would be to set a timeout after each button press, where no new button press will be registrated, like 10ms (should be plenty enough for debouncing, though you can test for your setup yourself). This can be done with `millis()` by maintaining a timestamp of the last button press:

    #define DEBOUNCE_TIME  10
    volatile unsigned long button_press_timestamp = 0;

    void increment(void){
      if(millis()-button_press_timestamp > DEBOUNCE_TIME){
          digit_state = digit_state + 1;
          button_press_timestamp = millis();
      }
    }

First in global scope we are defining our debounce time and a variable for holding the timestamp, when the last button press was registered. In the ISR (here only `increment()` as example) we then check the difference between this timestamp and the current time. If that is bigger than the debounce time we execute the buttons action (incrementing in this case). Then we update the timestamp to the current time.

On a button press the first falling edge will trigger the button action. Any falling edges from the bouncing will appear inside the debounce time and thus will be ignored (the ISR gets called but the code in the if statement is not executed).

This debouncing principle is not perfect but easy to implement and it might be enough for you.

  [1]: https://github.com/thomasfredericks/Bounce2


message:
Error After running Arduino code on Windows 10

After running the Arduino Program on my Windows machine I got the following error my code and error are as below.

Also the COM port was turned grey i.e. disbaled.

    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12,11,5,4,3,2);

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

    void loop()
    {
      lcd.print("Hello, World!");
      delay(500);
      lcd.clear();
      delay(500);
    }

It displayed as shown below

> Arduino: 1.8.14 (Windows 10), Board: "Arduino Uno" Sketch uses 1894
> bytes (5%) of program storage space. Maximum is 32256 bytes. Global
> variables use 59 bytes (2%) of dynamic memory, leaving 1989 bytes for
> local variables. Maximum is 2048 bytes. Serial port not selected.

body:
I know this problem from Arduino Uno clones. You need a proper driver. Here are a few:

* [CH341 serial driver](http://www.wch.cn/download/CH341SER_ZIP.html) (e.g. for Vendor ID 1A86, Product ID 7523)
* [Holtek UART bridge](https://www.holtek.com/productdetail/-/vg/42B534-x) (e.g. for Vendor ID 04D9, Product ID B534)
* [FTDI Drivers](https://ftdichip.com/drivers/vcp-drivers/) (e.g. for Vendor ID 0403, Product ID 60xx)
* [CP210x Drivers](https://www.silabs.com/developers/usb-to-uart-bridge-vcp-drivers) (e.g. for Vendor ID 10C4, Product ID EAxx)
* [Prolific PL2303](http://www.prolific.com.tw/US/ShowProduct.aspx?p_id=225&pcid=41) (e.g. for Vendor ID 067B, Product ID 23xx and AAxx)
* [Microchip MCP2221](https://www.microchip.com/wwwproducts/en/MCP2221) (for Vendor ID 04D8, Product IDs 00xx and 020x)
* [Cypress CDC](https://www.cypress.com/documentation/software-and-drivers/usb-serial-software-development-kit) (e.g. for vendor ID 04B4, Product ID 00xx)

After installing the driver, Windows recognizes the board as a serial port and Arduino IDE will list the serial ports identified by Windows.

Look up the details in device manager. You'll find the IDs in the details of the device named `Device instance path`. It looks like `...VID_xxxx?PID_yyyy...` where xxxx is the vendor ID and yyyy is the product ID. You can also install all drivers, if you don't know which one to choose.

Another (but rare) issue could be that you interrupted the driver setup during Arduino IDE installation. In that case, run the Arduino IDE installation again and make sure you allow the driver installations (for Vendor ID 2341 and 2A03, Product IDs 0043, 0001, 0243).

Any of these suggestions will require administrator permissions.


message:
How to stop Single Analog Pin Keypad Matrix (Using Resistors) from receiving Interference from Livewire/other Sensors?

I saw a tutorial on linking a keypad using one pin, utilising several resistors:
http://razibshahdat.blogspot.com/2018/05/one-single-analog-pin-keypad-control.html

I have this keypad, a 16x2 LCD, a PIR motion detector, and a DHT11 temperature & humidity sensor attached. Furthermore, I have an additional 5V power supply connected to the breadboard for additional power, although I'm not sure if this is required?

All components work as expected in the current configuration when only loading their relevant Arduino template code, except for the keypad. The keypad worked initially when nothing else was connected, but now the resistance values fed to the serial seem to jump, particularly in the first column. I tried to add some resistance between the first input of the keypad matrix and the live wire, which dampens the fluctuations but does not remove them completely.
[![!\[Schematic using Fritzing][1]][1]
I have created a Fritzing sketch to try to make it a bit easier to understand, although I realise that it is still rather chaotic. I am new to Fritzing and Arduino and am still figuring things out.

Here is the isolated code for the keypad, which I am using to find the output values (which, as mentioned, are varying unpredictably), although this was working previously, on a more simple setup:

        // code adapted from: https://www.youtube.com/watch?v=W8ZSeLD90KA
        void setup() {
             Serial.begin(9600);  /* Define baud rate for serial communication */
        }

        void loop() {
          int keyIn;
          int keyVals [16] = {976, 450, 333, 244, 166, 138, 124, 109, 90, 81, 76, 70, 61, 57, 54, 51};
          char keys[16] = {'1','2','3','A','4','5','6','B','7','8','9','C','*','0','#','D'};
          int range = 1;

          keyIn = analogRead(A1);

          String temp = "";

          if (keyIn > 2)
          {
            Serial.print(keyIn);
            for(int i=0; i<=15; i++)
            {
              // The values of the keys changed, that's why the following is commented out
              //if (keyIn >= keyVals[i]-range && keyIn <= keyVals[i]+range)
              //{
              //  temp = keys[i];
              //}
            }
           Serial.print(temp);
           Serial.println("");
           delay(500);
        }
   }

Lastly, I intend for this board to be my master. I then intend to connect a slave through I2C with a DC motor, a servo motor, and an RGB LED. Does this seem feasible?

Please assist if you can.

If you have any additional advice, that too would be highly appreciated - thank you in advance!

  [1]: https://i.stack.imgur.com/ngMHd.png

body:
Your key values are:

```cpp
int keyVals [16] = {976, 450, 333, 244, 166, 138, 124, 109, 90, 81, 76, 70, 61, 57, 54, 51};
```

The formula for the key values given in the [OnewireKeypad library][1] is:

```cpp
float V = (voltage * float( R3 )) / (float(R3) + (float(R1) * float(R)) + (float(R2) * float(C)));
float Vfinal = V * ANALOG_FACTOR;
```

where:
 - voltage = 5 V
 - R1 = 1,000 Ω (the three horizontal ones in the schematic)
 - R2 = 4,700 Ω
 - R3 = 1,000 Ω (the pulldown to GND in the schematic)
 - R = row number 0 to 3
 - C = column number 0 to 3
 - ANALOG_FACTOR = 1023 / 5.0;

The keypad schematic given in the [blogspot article][2] is:

[![Onewire keypad schematic][3]][3]

I put the formula and parameters into an Excel spreadsheet and produced this:

[![Excel spreadsheet of Onewire formula][5]][5]

...which is different to your key values.

Have I misunderstood your circuit setup? Are you doing something different?

  [1]: https://github.com/AndrewMascolo/OnewireKeypad/blob/abdea336ec177d5f483a064c4d9d8577397f1c87/OnewireKeypad.h#L164
  [2]: http://razibshahdat.blogspot.com/2018/05/one-single-analog-pin-keypad-control.html
  [3]: https://i.stack.imgur.com/CGYaP.png
  [4]: https://i.stack.imgur.com/uZFZT.png
  [5]: https://i.stack.imgur.com/tzM2O.png


message:
Mega2560 programming megacore avrdude: Device signature = 0x000000

I have two sunfounder mega2560s. I am using one as an ISP programmer and the other is my target. The programmer has the original bootloader on it. I have placed the ArduinoISP sketch on my programmer and connected LEDs and stuff as here: https://www.arduino.cc/en/pmwiki.php?n=Tutorial/ArduinoISP

I have connected all six pins on my programmer to all six pins on the target. I'm using the ICSP towards the middle of the board on both boards as opposed to the one near the USB cable.

I am trying to place megacore on the target. I have followed the directions here: https://github.com/MCUdude/MegaCore#how-to-install.

I am running Arduino IDE on Windows 10. I am selecting Tools->Board->megacore->Mega2560 and then Tools->Programmer->Arduino as ISP.

I believe all of this setup is correct, so I Click Burn Bootloader. I get the following results:

    Arduino: 1.8.15 (Windows Store 1.8.49.0) (Windows 10), Board: "ATmega2560, Yes (UART0), EEPROM retained, Arduino MEGA pinout, BOD 2.7V, LTO disabled, External 16 MHz"

    avrdude: Version 6.3-20201216

             Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/

             Copyright (c) 2007-2014 Joerg Wunsch

             System wide configuration file is "C:\Users\ThomH\Documents\ArduinoData\packages\MegaCore\hardware\avr\2.1.3/avrdude.conf"

             Using Port                    : COM19

             Using Programmer              : stk500v1

             Overriding Baud Rate          : 19200

             AVR Part                      : ATmega2560

             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    10     8    0 no       4096    8      0  9000  9000 0x00 0x00

               flash         65    10   256    0 yes    262144  256   1024  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 : STK500

             Description     : Atmel STK500 Version 1.x firmware

             Hardware Version: 2

             Firmware Version: 1.18

             Topcard         : Unknown

             Vtarget         : 0.0 V

             Varef           : 0.0 V

             Oscillator      : Off

             SCK period      : 0.1 us

    avrdude: AVR device initialized and ready to accept instructions

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000 (retrying)

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000 (retrying)

    Error while burning bootloader.

    Reading | ################################################## | 100% 0.02s

    avrdude: Device signature = 0x000000

    avrdude: Yikes!  Invalid device signature.

             Double check connections and try again, or use -F to override

             this check.

    avrdude done.  Thank you.

I have double checked all of my connections and am powering the target 2560 from a power block on a USB cable.

All research on the web turned up only issues with connections or separate power. Also, I don't know how to use the avrdude from the command prompt to add the `-F` as suggested.

Having tried everything, I'm looking for help here. Thanks.

body:
The answer was that you must connect the reset pin of the target ICSP to pin 10 of the programmer Mega 2560. This was not very clear in the tutorial here: https://www.arduino.cc/en/pmwiki.php?n=Tutorial/ArduinoISP.

This fixed the problem for me, so it was a connection issue.


message:
How to hook up a HC-06 to Arduino Nano

So I have an arduino nano hooked up to hc-06 however every diagram of the hookup wires shows some kind of resistors (1K and 2K, rather high resistances to ignore), and I completely overlooked them. I hooked it up to my computer and it all lit up nice, however I am wondering why those resistors would be included if it still lights up. Am I slowly damaging my equipment over time?

body: Welcome! You have a good question but a little light on details. You may have damaged something, there is not enough detail to tell. You state hc-06 but no link to the module you used. They come in 3.3 and 5V models. The resistors are used to translate the voltage down, this you should never do, you are playing with tolerances and if wrong you could destroy the part. If you have a 5V Arduino and a 3.3V HC-06 Get a translator or a 5V HC-06. Lighting up only tells you there is power there. The lights (LEDs) are operational even if the micro is not even on the board. Are you slowly damaging your equipment over time? Possibly I cannot tell with what you have told us. You have not even stated it worked or not and if you even powered up.


body:
The HC-06 itself is a 3.3V device, while the Arduino Uno/Nano is a 5V device. When using electronic devices you need to stay within their corresponding voltage limits, both in power and IO connections.

Most HC-06 boards, that you can buy, will also include a voltage regulator for the power, regulating the 5V from the Arduino down to 3.3V. If you have one of these, you can provide 5V to the HC-06 as power (otherwise you would need to use the 3V pin of the Arduino as power source for the HC-06). But these boards mostly don't have a level translation for the IO lines. And that's where the resistors come in.

The HC-06 has 2 IO lines: RX and TX.

- TX will send data to the Arduino and thus be driven by the HC-06 with its 3.3V. The Arduino runs on 5V, but will still be reading 3.3V as a digital HIGH level. Thus this line is not a problem.
- The RX line will be driven by the Arduino at 5V. Most devices don't like a voltage on their IO pins, that is significantly higher than their working voltage (for power). Thus you can damage the HC-06 receiving hardware, if you directly connect Arduino and HC-06.

To solve that problem you have 2 options for level translation between 3.3V and 5V:

- The proper way would be to use a transistor based level translator you can get these as ready-to-use board for rather cheap (search on the big online platforms for "level translator" or "level converter"), or you can build them yourself using transistors and resistors.
- Or you can use a voltage divider consisting of two resistors. When you connect them like ground -> 2kOhm resistor -> 1kOhm resistor -> TX of the Arduino, you will get the Arduinos TX signal divided down to 3.3V at the point between the two resistors. There you can connect the HC-06 RX pin. This method has drawbacks, since it also acts as parasitic low pass filter. That limits the transmission speed (baud rate). Though you can still easily drive baudrates as high as 115200 baud, which is sufficient in most cases.

So it is not a good option to just omit the resistors. It can lead to damaging the HC-06. You can choose between the above options.


message:
Control 4 Grove - RGB LED (WS2813 Mini) color and brightness

I have connected 4 Grove - RGB LED (WS2813 Mini) to D2,D3,D4,D5 on Grove Base Shield V2.0 for Arduino. How can I control the brightness and color of each LED? At the moment I only know to activated one.

Code:

    #include "Adafruit_NeoPixel.h"
    #define PIN            2
    #define NUMPIXELS      1
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

    void setup() {
      pixels.setBrightness(125);
      pixels.begin();
    }

    void loop() {
        pixels.setPixelColor(1, pixels.Color(255,255,255));
        pixels.show();
    }

Thanks

body:
Here is one of the multiple ways possible to address the problem, Basically, use a for loop and iterate the first parameter setPixelColor function to address all the LEDs. Try experimenting [here][1]:

    #include "Adafruit_NeoPixel.h"
    #define PIN            2
    #define NUMPIXELS      4
    Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);

    void setup() {
      pixels.setBrightness(125);
      pixels.begin();
    }

    void loop()
    {
      pixels.clear(); // Set all pixel colors to 'off'

      // The first NeoPixel in a strand is #0, second is 1, all the way up
      // to the count of pixels minus one.
      for (int i = 0; i < NUMPIXELS; i++) { // For each pixel...

        // pixels.Color() takes RGB values, from 0,0,0 up to 255,255,255
        // Here we're using a moderately bright green color:
        pixels.setPixelColor(i, pixels.Color(0, random(0,255), 0));

        pixels.show();   // Send the updated pixel colors to the hardware.

        delay(100); // Pause before next pass through loop
      }
    }

here is quick view:

[![enter image description here][2]][2]

>!Since you are using NeoPixels, [here][3] is a list of simulated examples. you can play with the code and make your own projects online.

  [1]: https://wokwi.com/arduino/projects/303848371358007874
  [2]: https://i.stack.imgur.com/Dkw4b.gif
  [3]: https://wokwi.com/arduino/libraries/Adafruit_NeoPixel


message:
Can’t send string from arduino to processing via hc05

I’m trying to send and receive data from my laptop to arduino nano via hc05 Bluetooth for a rocket flight computer. For some reasons which I don’t know, I can send data from processing software using myPort.write() but cannot send a String back from arduino back to processing for telemetry purpose. At some point it was working, then stopped. I tried another code from HowToMechatronics.com and still it didn’t work. I’m using the Serial.println function on Hardware serial.
Pls help

In the processing code, I use all necessary libraries and functions e.g serialEvent(), myPort.bufferUntil(\n), myPort.readStringUntil(‘\n’)![enter image description here](https://i.stack.imgur.com/fKiJY.jpg)

  [1]: https://i.stack.imgur.com/V3Jqn.jpg![enter image description here](https://i.stack.imgur.com/usvad.jpg)![enter image description here](https://i.stack.imgur.com/SR1xB.jpg)![enter image description here](https://i.stack.imgur.com/R3Uog.jpg)

body: Update: After trying numerous codes, I was  sure that it wasn’t a software problem. I then removed the Hc05 module from the circuit, and I was able to put it in AT mode(this means my module is working fine). This leaves only one possible problem I.e the circuit. I used a multimeter to measure the voltage between Hc05 RX and GND. I got 1.8v(but how?). After retracing the connections, I figured out the problem was with the voltage divide I used to step down 5v to 3.3v. I used a 2k Ohm resistor in place of a 1k, and a 1k in place of the 2k resistor. So that’s why I’m getting a voltage of around 1.8v. Turns out 1.8v is too low for Hc05 rx pin to use. After correcting it, everything works fine


message:
Back EMF from Relay causing trigger on INPUT pin

I am wiring up a light show for my pickup truck.

I have installed various high power spotlights and light bars into a dedicated relay/fuse box in the engine bay. These relays are wired into a switch panel in the dashboard and work beautifully using the manual switches.

I have subsequently set up a brain...

* An Arduino Uno R3, programmed with 3 different light sequences;
* An 8 bank 5v relay module, driven from Digital Out Pins 6 to 12, each relay on the module fires a separate light (via the existing relays in the engine bay).
* A 4 Channel RF receiver, provides Digital In Pins 3 to 5, to select one of the three sequences, and Digital In Pin 2 Interrupt as a stop/reset button.

I have set this up to start a sequence from an RF button, and programmed the Arduino to fire the relays, including strobe, which was working great on the LED's I attached while testing.

However, when I wire them up to bridge the switches on the dashboard (in turn firing the relays in the engine bay), the Arduino receives a positive signal on INPUT_PULL Pin 2 after a couple of flashes. I think this is something to do with an interference caused by the back EMF from the relay coils in the engine bay, possibly striking the relay module causing it to fire the interrupt pin 2 and causing a reset.

Looks like I need a snubber. I think the best answer is to install a flyback diode across the coil on the relay in the engine bay, but have been trying to figure out how I can wire these up within the blue box, without dismantling the relays installed in the engine bay. I thought maybe I could connect general ground to the manual switch (long route of achieving the same circuit), which helped but after a few more flashes the Arduino gets a signal to reset again. I have lots of diodes and RC Snubber circuits from Amazon which I was going to try, maybe across the Module Relay contacts.

This is a circuit for one of the eight lights.

Please advice how I can reduce this interference using snubbers or some other modification, ideally within the blue box.

Thanks

[![Circuit][1]][1]

UPDATE:

I have managed to get a working setup by removing the resistor and the 5v feed to the RF Relay. Also adding a Diode from earth to the top side of the Module Relay connector. See updated circuit below. Seems to be working, though I'll have a go at adding RC Snubbers as suggested.

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/yRFoz.png
  [2]: https://i.stack.imgur.com/8wrkp.png

body:
There are two things to tackle in your schematic. First is snubber networks. These are used to aid in the prevention (or rapid extinguishing) of sparks between the contacts of switching gear (like relays). You should attach one across the contacts of each relay. It is these sparks that create most of the "airborne" EMI.

A diode across a relay's coil only deals with "wire-born" EMI (in the form of induced back-EMF) and has no relevance in your circuit due to the galvanic isolation of the first stage relay and the driver circuit in the module.

The second, and more important, thing to deal with is your input pin.  Firstly the built-in pull-up resistor is very very weak. It's usually around 30kΩ, and that is very easy for "airborne" EMI to overcome.  You should avoid using it. Instead an external pull-up resistor of no more than 10kΩ (I'd recommend 1kΩ as a good value) should be used.

Secondly you have a 10kΩ resistor in series with your switching contacts. This will not be helping to get a logic LOW level when the switch contacts are closed since it forms a resistive divider with the pull-up resistor. As it is it happens to *just* work with the internal pull-up, since the internal pull-up is greater than the 10kΩ series resistor. Reduce the pull-up with an external and that will no longer be the case.

That 10kΩ resistor should be removed completely.

Here is your circuit with modifications in red:

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/Wz4K7.png


body:
Here is a general idea of a MOSFET alternative for switching the light on and off.

<a href="https://www.falstad.com/circuit/circuitjs.html?ctz=CQAgjCAMB0l3BWcMBMcUHYMGZIA4UA2ATmIxAUgpABZsKBTAWjDACgA3CmmkbBFN15NsgqlRpUwYqFGhgExBTWJ1IxFGwBO4aSBQpeaPPsOyw8NgHdaNEyMEIeIB1Gu2T-R869uAZrRw4CgmPCbSnvRg0EgwkJpgeBBh4M4pvlS4MNIIrJiQlCEYhPp44WLQvDA0bAGiVAa82IQmjXyC0bGwmgHGpkYIJW2i4DFy8dp8LcGe065S8JDuza34U+UmSzYrM4FSIW7b0xH6g7tbp0NrKGcnFzuGmdMZ7jdDkpd8Am469f3tmW+C0sOj6bT6GWQlgAzgDaJ40LoZBA-ABDAA20IYbEkvBSrhSeVkcUIYHohGgOFkaMx2NxcNcfzsxNgpPJlPoVBpWPc+JGO3myzm-MRgps6W+OxeR08ksR0rhvjeXzErzOSrWLwA5kIVbqduI2AAZJH-PANMxSEDchjUJYADwoGCkhHIhGwvDAztowWCAB1oQA1AMAI1RABdwwwtABPSZ-YaIsDOYH3JN6P7JqpsR00BDkFBgYgUfimQSewRGgCWWoAFuGA2AAwAKEJ4ADqAEoc7QEEhmiXPMWKyAAGIAVyxAb8AHstAHq3WG9D2GhyES2kSvSVeABBLQAE3HVYAdjOAwAHU8BvBsNdwje3PS8AAiqOhtZDM9Rh4D0KsVbhgAxrWPZoMWrB8JAnp4r6E5TtCs7ztCADKAHAbWDDQmwM58OSVSBKQdqwPAZCEIMNyyII2D0NgOF8LwhAEZIRFxPAxQoMQ2CqAg2A5OMpHFBRsT6AxfD0UgTGyCxxZxNxkCEJR0QlA01B0UAA">
Click to simulate in Falstad.

You can click the switch and the H/L input to see how it operates while running the simulation.

The p-channel MOSFET in series with Light 1 could be [FQP27P06][1].

The n-channel MOSFETs are of much lower power.

Using MOSFETs eliminates both the RFI/EMI interference from sparks across relay contacts and the surges/noise from the collapsing electric field of the coils of the relays.

  [1]: https://www.sparkfun.com/products/10349


message:
Stuck In While Loop

[![enter image description here][1]][1]
So I'm a beginner at Arduino and I have to light up an LED grid to show digits from 0-9. I wrote a bit of code (with the help of some people) and it's like 90% done but there's this ONE problem. I used a switch case to light up the LEDs (so if the user writes a 5 then the switch case will make the LEDs show the digit 5) but it only shows up for like a SPLIT second.Any fixes for this?

```c++
#define ROW_1 3
#define ROW_2 4
#define ROW_3 5
#define ROW_4 6
#define ROW_5 7

#define COL_1 8
#define COL_2 9
#define COL_3 10
#define COL_4 11
#define COL_5 12
#define COL_6 13

const byte rows[] = {
    ROW_1, ROW_2, ROW_3, ROW_4, ROW_5
};

byte Zero[]  = {B011110, B010010, B010010, B010010, B011110};
byte One[]   = {B001100, B000100, B000100, B000100, B000100};
byte Two[]   = {B011110, B000010, B011110, B010000, B011110};
byte Three[] = {B011110, B000010, B001110, B000010, B011110};
byte Four[]  = {B010010, B010010, B011110, B000010, B000010};
byte Five[]  = {B011110, B010000, B011110, B000010, B011110};
byte Six[]   = {B011110, B010000, B011110, B010010, B011110};
byte Seven[] = {B011100, B000100, B000100, B000100, B000100};
byte Eight[] = {B011110, B010010, B011110, B010010, B011110};
byte Nine[]  = {B011110, B010010, B011110, B000010, B011110};

void setColumns(byte b) {
    digitalWrite(COL_1, (~b >> 0) & 0x01);
    digitalWrite(COL_2, (~b >> 1) & 0x01);
    digitalWrite(COL_3, (~b >> 2) & 0x01);
    digitalWrite(COL_4, (~b >> 3) & 0x01);
    digitalWrite(COL_5, (~b >> 4) & 0x01);
    digitalWrite(COL_6, (~b >> 5) & 0x01);
}

void  drawScreen(byte buffer2[]){
    for (byte i = 0; i < 5; i++) {
        setColumns(buffer2[i]);
        digitalWrite(rows[i], HIGH);
        digitalWrite(rows[i], LOW);
    }
}

void setup() {
    Serial.begin(9600);
    for (byte i = 2; i <= 13; i++)
        pinMode(i, OUTPUT);
}

void loop()
{
    int digit;
    if(Serial.available()) {
        digit = Serial.read();
        Serial.println(digit);
    }
    switch (digit) {
        case 48:
            drawScreen(Zero);
            break;
        case 49:
            drawScreen(One);
            break;
        case 50:
            drawScreen(Two);
            break;
        case 51:
            drawScreen(Three);
            break;
        case 52:
            drawScreen(Four);
            break;
        case 53:
            drawScreen(Five);
            break;
        case 54:
            drawScreen(Six);
            break;
        case 55:
            drawScreen(Seven);
            break;
        case 56:
            drawScreen(Eight);
            break;
        case 57:
            drawScreen(Nine);
            break;
    }
}
```

  [1]: https://i.stack.imgur.com/0ue3r.png

body:
Your drawScreen() function executes very quickly and therefore, lights the LEDs once, very briefly. There are a few choices; here are a couple to try:

One is to write surround the existing `for{}` loop in drawScreen() with another one, to redisplay the digit enough times to make it visible. Experiment with the count of the outer loop starting with, maybe, 50000 (guessing here...), until you have something you like.

Another is to use a `while( Serial.available() == 0 ){}` loop, exactly the same way, which will have the effect of maintaining the displayed digit until you type a new one.


body:
If you want the display to persist, you should call `drawScreen()` on
every loop iteration. You will need a variable for “remembering” what
glyph you should draw. Then, the serial-processing code has only to
update this variable when a new character is received:

```c++
// Remember which glyph we should draw.
byte *glyph = Zero;

void loop() {
    if (Serial.available()) {
        char digit = Serial.read();
        Serial.println(digit);
        switch (digit) {
            case '0': glyph = Zero;  break;
            case '1': glyph = One;   break;
            case '2': glyph = Two;   break;
            case '3': glyph = Three; break;
            case '4': glyph = Four;  break;
            case '5': glyph = Five;  break;
            case '6': glyph = Six;   break;
            case '7': glyph = Seven; break;
            case '8': glyph = Eight; break;
            case '9': glyph = Nine;  break;
        }
    }
    drawScreen(glyph);
}
```

The `glyph` variable is a “pointer to `byte`” because what is what an
array of `byte` [decays to][] when it is assigned to a variable.

[decays to]: https://stackoverflow.com/questions/1461432/what-is-array-to-pointer-decay


message:
Level shifter with diode - not pulling to zero

I'm interfacing a 3.3 V device (a GPS module with a serial interface) to a 5 V Arduino Nano. The circuit I am using is this:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/1ppnF.png)

<!-- End schematic -->

I don't have the [GPS Module](https://proto-pic.co.uk/product/neo-6m-gps-module-for-arduino-with-large-antenna/) connected at the moment and have added LED D1 and R2 to visualise the Arduino TX signal (which is currently just setting TX GPIO pin high and low on a 1 second cycle). I am measuring the voltage at NODE1 with a DMM.

My understanding is that D3 blocks the 5V high from Arduino TX and then NODE1 is pulled to 3.3 V by R1. When Arduino TX is low (0 V) D3 conducts and pulls NODE2 to 0 V.

What I measure at NODE1 is 3.1 V and 0.8 V. Am I right in thinking that ...

1. The difference between 3.3 and 3.1 is simply the voltage drop across R1 due to the load of my LED and 5 K resistor. The RX input of the GPS module will have some similar effect.

2. The difference between 0.8 V and 0.0 V is mostly due to the forward voltage of the 1N4148? Is there significant contribution from the ATMega328P GPIO port circuitry or elsewhere?

3. This is pretty much OK and as expected.

body:
> The difference between 3.3 and 3.1 is simply the voltage drop across R1 due to the load of my LED and 5 K resistor.

Correct.

> The RX input of the GPS module will have some similar effect.

No, the RX will have little to no effect. It is "high impedance" - looking to the circuit like a very small capacitor and very large resistor in series to ground. Negligible to your circuit.

> The difference between 0.8 V and 0.0 V is mostly due to the forward voltage of the 1N4148?

Yes. The datasheet shows the forward voltage can be up to 1V.

> Is there significant contribution from the ATMega328P GPIO port circuitry or elsewhere?

No.

> This is pretty much OK and as expected.

It is.

----

Now my comments:

* You should use a larger pullup and isolate your LED (if you want to keep it) with a BJT or MOSFET so it doesn't load the circuit. That will reduce the current and thus the forward voltage drop over the diode slightly.
* You should use a *Schottky* diode to considerably reduce the forward voltage drop even further. These also switch faster allowing for higher baud rates.


body: That is correct. The most reliable solution is to use a level shifter. They are inexpensive and generally come with more than 1 channel. Use one of the additional channels to drive your led. You are reducing your logic low to 0.32 volts. Typically the threshold is 40% of VCC or 1.32 volts. - 1 volt (worse case) for the 4148 uses almost all of your marjin. That can be reduced even further by loads on the pins. The level shifter is one small board, not a handful of parts to connect which increases your chance of errors but it will help your debugging skills.


message:
arduino acclerometer with servo motor

I'm currently working on project to operate three motors while sending accelerometer value to computer via bluetooth module. I want the motor operation and value transmission to work seperatly. But when motors operate, the transmission stops. I used the ArduinoThread library, but since I don't understand all the usage, it still has some kind of delay. Plus, I want two of the motors work first(just once) and the other works after specific time(also just once). But the first setup of two motors and the latter doesn't work. Please check my code and give me some advice. Thank you!

    #include <Wire.h>
    #include <SoftwareSerial.h>
    #include <Servo.h>
    #include <Thread.h>

    const int MPU_addr=0x68;  // MPU-6050 I2C address
    int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

    SoftwareSerial BTSerial(3,2);   // TX,RX

    Servo servoMini;
    Servo servoUp;
    Servo servoDown;
    int pinMini = 6;
    int pinUp = 9;
    int pinDown = 10;
    int i = 1;
    unsigned long tPrev, tNow = 0;

    Thread myThread = Thread();

    void readAcc(){
      Wire.endTransmission(true);
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
      Wire.endTransmission(false);
      Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers   // 14bit??

      AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
      //AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
      //AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
      //GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
      //GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
      //GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

      BTSerial.println(AcX);   // 16bit
      Serial.println(AcX);

      // delay(25);
    }

    void setup(){
      // I2C
      Wire.begin();
      Wire.beginTransmission(MPU_addr);
      Wire.write(0x6B);  // PWR_MGMT_1 register
      Wire.write(0);     // set to zero (wakes up the MPU-6050)

      // serial, bluetooth
      Serial.begin(9600);
      BTSerial.begin(9600);
      Serial.println("CLEARDATA");
      Serial.println("ONLY AcX");

      // servo
      servoMini.attach(pinMini);
      servoUp.attach(pinUp);
      servoDown.attach(pinDown);
      pinMode(pinMini, OUTPUT);
      pinMode(pinUp, OUTPUT);
      pinMode(pinDown, OUTPUT);
      servoMini.write(145);
      servoUp.write(180);
      servoDown.write(0);

      // Thread(MPU-6050)
      myThread.onRun(readAcc);
      myThread.setInterval(20);
    }

    void loop(){
      while(i == 1){
        tNow = millis();
        myThread.run();

        servoUp.attach(pinUp);
        servoDown.attach(pinDown);
        servoUp.write(60);
        servoDown.write(120);

      if((tNow - tPrev)>= 1000){
        servoMini.attach(pinMini);
        servoMini.write(180);
        i++;
      }
    }

      servoMini.detach();
      myThread.run();
    }

body:
I think you want something like [Blink Without Delay][1], but with more tasks.

Here is my interpretation of your description which extends Blink Without Delay by adding three more tasks to:
 - read the accelerometer
 - perform "just once"
 - perform "also just once"

I've added several `Serial.print()` statements to give a running commentary on what's occurring for debug purposes.

```cpp
#include <Wire.h>
#include <SoftwareSerial.h>
#include <Servo.h>

SoftwareSerial BTSerial(3, 2);  // TX, RX

Servo servoMini;
Servo servoUp;
Servo servoDown;

const byte pinMini = 6;
const byte pinUp = 9;
const byte pinDown = 10;

// Timings for each event.
const unsigned long READ_ACCELEROMETER_INTERVAL = 50;
const unsigned long JUST_ONCE_INTERVAL = 1000;
const unsigned long ALSO_JUST_ONCE_INTERVAL = 2000;
const unsigned long LED_BLINK_INTERVAL = 200;

// Keep track of timestamps for each event.
unsigned long previous_blink_timestamp;
unsigned long previous_accelerometer_timestamp ;
unsigned long just_once_timestamp;
unsigned long also_just_once_timestamp;

// Flags to indicate completion of "just once" events.
bool just_once = false;
bool also_just_once = false;

// State of blinking LED.
bool led_state = false;

void setup()
{
    Serial.begin(115200);
    Serial.println("\n\nAccelerometer with Servo Test\n");

    // For blink without delay.
    pinMode(LED_BUILTIN, OUTPUT);

    // servo
    servoMini.attach(pinMini);
    servoUp.attach(pinUp);
    servoDown.attach(pinDown);

    // Perform first move.
    servoMini.write(145);
    servoUp.write(180);
    servoDown.write(0);

    // Initialise all timestamps with the same value with a single call to millis().
    previous_blink_timestamp =
    previous_accelerometer_timestamp =
    just_once_timestamp =
    also_just_once_timestamp = millis();
}

void loop()
{
    unsigned long current_timestamp = millis();

    //
    // TASK 1: Read accelerometer.
    //
    if (current_timestamp - previous_accelerometer_timestamp >= READ_ACCELEROMETER_INTERVAL)
    {
        // Read accelerometer.
        Serial.print("Reading accelerometer... ");
        readAcc();
        previous_accelerometer_timestamp += READ_ACCELEROMETER_INTERVAL;
        Serial.println("Done.");
    }

    //
    // TASK 2: Just once.
    //
    if (!just_once && current_timestamp - just_once_timestamp >= JUST_ONCE_INTERVAL)
    {
        // Perform second move.
        Serial.print("Running just once... ");
        servoUp.write(60);
        servoDown.write(120);
        just_once = true;
        Serial.println("Done.");
    }

    //
    // TASK 3: Also just once.
    //
    if (!also_just_once && current_timestamp - also_just_once_timestamp >= ALSO_JUST_ONCE_INTERVAL)
    {
        // Perform third move.
        Serial.print("Running also just once... ");
        servoMini.write(180);
        also_just_once = true;
        Serial.println("Done.");
    }

    //
    // TASK 4: Blink without delay.
    //
    if (current_timestamp - previous_blink_timestamp >= LED_BLINK_INTERVAL)
    {
        // Toggle LED state.
        led_state = !led_state;
        digitalWrite(LED_BUILTIN, led_state);
        previous_blink_timestamp += LED_BLINK_INTERVAL;
    }
}
```

[1]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay


body:
Here's the final form of my project.
I've added motor detach function since it still shivers a bit.

```#include <Wire.h>
#include <SoftwareSerial.h>
#include <Servo.h>

const int MPU_addr=0x68;  // MPU-6050 I2C address
int16_t AcX,AcY,AcZ,GyX,GyY,GyZ;

SoftwareSerial BTSerial(3, 2);  // TX, RX

Servo servoMini;
Servo servoUp;
Servo servoDown;

const byte pinMini = 6;
const byte pinUp = 9;
const byte pinDown = 10;

// Timings for each event.
const unsigned long ACC_INTERVAL = 50;
const unsigned long INTERVAL = 1000;
const unsigned long INTERVAL_FIN = 2000;
const unsigned long GRIPPER_INTERVAL = 2000;
const unsigned long GRIPPER_INTERVAL_FIN= 3000;
const unsigned long LED_INTERVAL = 250;

// Keep track of timestamps for each event.
unsigned long prev_led_timestamp;
unsigned long prev_acc_timestamp;
unsigned long servo_timestamp;
unsigned long servo_timestamp_fin;
unsigned long gripper_timestamp;
unsigned long gripper_timestamp_fin;

// Flags to indicate completion of "just once" events.
bool servo = false;
bool servo_fin = false;
bool gripper = false;
bool gripper_fin = false;

// State of blinking LED.
bool led_state = false;

void readAcc(){
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,14,true);  // request a total of 14 registers   // 14bit??

  AcX=Wire.read()<<8|Wire.read();  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  //AcY=Wire.read()<<8|Wire.read();  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  //AcZ=Wire.read()<<8|Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  //GyX=Wire.read()<<8|Wire.read();  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  //GyY=Wire.read()<<8|Wire.read();  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  //GyZ=Wire.read()<<8|Wire.read();  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)

  BTSerial.println(AcX);   // 16bit
  //Serial.println(AcX);
}

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

  // For blink without delay.
  pinMode(LED_BUILTIN, OUTPUT);

  // I2C
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  // servo
  servoMini.attach(pinMini);
  servoUp.attach(pinUp);
  servoDown.attach(pinDown);

  // Perform first move.
  servoMini.write(145);
  servoUp.write(180);
  servoDown.write(0);

  // Initialise all timestamps with the same value with a single call to millis().
  prev_led_timestamp =
  prev_acc_timestamp =
  servo_timestamp = servo_timestamp_fin =
  gripper_timestamp = gripper_timestamp_fin = millis();
}

void loop(){
  unsigned long current_timestamp = millis();

  // TASK 1: Read acc.
  if (current_timestamp - prev_acc_timestamp >= ACC_INTERVAL){
    // Read acc.
    readAcc();
    prev_acc_timestamp += ACC_INTERVAL;
  }

  // TASK 2: Just once.
  if (!servo && current_timestamp - servo_timestamp >= INTERVAL)  {
    //Serial.print("Running just once... ");
    servoUp.attach(pinUp);
    servoDown.attach(pinDown);
    servoUp.write(60);
    servoDown.write(120);
    // retract speed control
    servo = true;
    //Serial.println("Done.");
  }
  if (!servo_fin && current_timestamp - servo_timestamp_fin >= INTERVAL_FIN){
    servoUp.detach();
    servoDown.detach();
    servo_fin = true;
  }

  // TASK 3: Also just once.
  if (!gripper && current_timestamp - gripper_timestamp >= GRIPPER_INTERVAL)  {
    // Perform third move.
    //Serial.print("Running also just once... ");
    servoMini.write(180);
    gripper = true;
    //Serial.println("Done.");
  }
  if (!gripper_fin && current_timestamp - gripper_timestamp_fin >= GRIPPER_INTERVAL_FIN){
    servoMini.detach();
    gripper_fin = true;
  }

  // TASK 4: Blink without delay.
  if (current_timestamp - prev_led_timestamp >= LED_INTERVAL){
    // Toggle LED state.
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
    prev_led_timestamp += LED_INTERVAL;
  }
}


message:
Relay not triggering from loop function. Variable "volume" not updating after encoder is turned to value?

I am reading a value from an encoder "volume knob" and I have a function called void fn_on were I am having sum int to zero and counting until it reaches the set value of volume. I tried posting to serial but my sum counter does not work. I want my relay to run "volume" number of times until sum > volume in my function "fn_on" I believe I am not storing or updating my volume correctly. Thank you for taking the time to look through this.

```cpp
#include <LiquidCrystal_I2C.h>
#include <Rotary.h>
#include <LCD_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

/* Rotary Encoder - Polling Example

The circuit:
  encoder pin A to Arduino pin 2
  encoder pin B to Arduino pin 3
  encoder ground pin to ground (GND)
*/
#define PINA 2
#define PINB 3
#define RelayPin 8

const char PUSHB = 5;
bool pressed = false;
long volume = 0; // this may not set the volumue

Rotary r = Rotary(2, 3);

void setup()
{
 Serial.begin(115200); // setup Pin modes
 pinMode(PUSHB, INPUT);
 r.begin(true);
 lcd.init();
 lcd.backlight();
 lcd.setCursor(0, 3);
 lcd.print(volume);
 digitalWrite(PINA, HIGH); // enable pull-ups
 digitalWrite(PINB, HIGH);
 // digitalWrite (PUSHB, HIGH);
 pinMode(RelayPin, OUTPUT); // Relay Pin ini
}

void loop()
{
 bool currentState = digitalRead(PUSHB);

 if (currentState == pressed)
 {
  Serial.println("Pressed");

  while (digitalRead(PUSHB) == pressed)
  {
   // do nothing
  }
 }

 unsigned char result = r.process();

 if (result)
 {
  // Serial.println(result == DIR_CW ? "Right" : "Left");
  if (result == DIR_CCW)
  {
   volume = volume - 1000; // change ++ to mulpes of 1000
   Serial.println(volume);
   lcd.setCursor(0, 3);
   lcd.print(volume);
   lcd.print("                                ");

   int sum = 0;
   for (sum = 1; sum < volume; sum++ && currentState = true)
   {
    lcd.setCursor(0, 2);
    lcd.print(sum);
    digitalWrite(RelayPin, LOW); // run test
    delay(3000);
    digitalWrite(RelayPin, HIGH); // run test
    delay(3000);
    digitalWrite(RelayPin, LOW); // run test
    delay(3000);
   }
  }
  else
  {
   volume = volume + 1000; // change volume++ to mulpes of 1000
   // initialize display_menu to 1st line
   lcd.setCursor(0, 3);
   lcd.print(volume);
   lcd.print("                                 ");
  }
 }
}
```

body:
I believe the issue is that you're setting your encoder pins high with `digitalWrite()`.  Those pins need to be configured as inputs for the interrupts to work correctly.  This will be handled by the encoder library when you call `r.begin(true)`.  In fact, `true` in that call tells the library to enable the pullups for you.

Removing those lines should fix your issue.


message:
Using String instead of C string, yet another attempt to touch a loaded issue

I've been reading a lot over the years why we should not use the notorious String class and how heap fragmentation is bad practice and not professional and we should never use it in our programs or we'll never enter the C hall of fame and get to be called programmers.

Fine, I get it, C string is pro, String is people toying with Arduino, but having read all that I still don't understand:

1. Where is the risk? If I use String and my heap gets fragmented, and there's still enough memory for the program to run for months without crashing, why should I not use String if it makes my work so much easier? Just because it's a bad habit is a very lame answer.

2. Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky? Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

3. And really, what is potential harm, in practical terms not theoretically, what are the limits, does anyone know when a program will crash?

Happy coding!

body:
It's not that `String` itself is evil, it's more that it's *very* easy to abuse it and cause heap fragmentation. Used judiciously it's fine and a useful tool. Used in "bad" ways and you open the door to random crashes.

By "bad" ways I mean excessive (and not needed) data duplication and heap reallocation. The biggest pitfalls are:

* Using `.concat()` or "adding" strings together with `+`
* Passing `String` objects to functions by value instead of by reference

Basically anything where a new string is created and the old one thrown away leaves holes in the heap.

Those holes (fragmentation) themselves aren't a problem - the problem is the very tiny amount of RAM the typical low-end Arduino (i.e., ATMega328P based) has. When you have wasted space in your heap in the form of holes it's more and more likely that you will end up having the top of your heap meet the bottom of your stack, and *that* is when problems arise.

For transient operations `String` is fine. By "transient" I mean operations where *all* the data is discarded at the end. All temporary *and* source strings are destroyed and *all* the memory is returned to the pool, thus leaving no holes in the heap.

Also on microcontrollers with far more memory than a little Arduino UNO (such as ESP32, etc) heap fragmentation ceases to really be a problem. By the time the heap grows big enough to be noticeable any holes have got big enough that they start to get filled again.


body:
The short answer is that fragmentation crashes are infrequent because they require very specific conditions to arise—**and that's the problem.**

Imagine you have a crash that occurs once every few days and can't figure out why. It never happens while testing and doesn't seem to be caused by anything specific.

Then it turns out that your code is printing numbers to a string, usually 4 digits but sometimes 2 or 3. And it turns out that very specific sequences of the lengths of strings being allocated and deallocated trigger a crash. But there's no good way to analyse or predict the problem because it hinges on absolutely everything that's happened since boot. If there was a 3- instead of 4-digit number 8 hours ago, that completely changes what would need to happen *now* to trigger a crash.

While answering this question I tried to come up with some code that would leave memory very fragmented. It was very difficult. Memory fragmentation is very sensitive to what happens, in what order. Basically it's a highly chaotic system.

This is reminiscent of problems related to multithreading, where running a simple program multiple times can easily give different results. Problems like this are really, really frustrating to identify and diagnose. A lot of people have felt the pain and that is why there is such stigma about `String`.

To answer your questions:

> 1. why should I not use String if it makes my work so much easier?

As long as you understand the pitfalls and how to avoid them, sometimes `String`s are the best tool for the job.

The main goal of avoiding `String` is to prevent severe heap fragmentation. There are other ways to do that, though:

* Don't store lots of heap-allocated objects on a long-term basis. If you only have 3 global `String` variables then it's probably fine to allocate 100 small strings if you delete them before doing anything else
* If you have to store many heap-allocated objects long-term, try not to allocate them during a period of a lot of heap allocations, deallocations, and resizings (such as during a loop when a string is being built). You want to avoid these long-term objects being given "random" positions through memory.

If you want to use `String` in an application where reliable long-term operation is important, you really have to be thorough in understanding your memory usage patterns and why they are unlikely to trigger a problem.

I should add that each `String` adds several bytes of memory overhead, both for the string descriptor and for the invisible bookkeeping that the `malloc()` implementation does. They are also slower to access than `char []`s.

> 2. Is it possible to quantify the fragmentation and get a feel of what's safe and when it becomes risky?

This is difficult because of how sensitive things are to tiny differences in allocation history. There are a few simple analyses you can do, though.

If you have `n` heap-allocated objects, you have `n+1` fragments (although some fragments may be zero size.) The average fragment size will be ≤ the amount of free space divided by `n+1`. For example if you have 19 allocated objects and 2000 bytes of remaining space, your average fragment size will be 100 bytes. Mathematically this implies that at least one fragment is ≥ this size, and therefore you are guaranteed to be able to allocate anything smaller than 100 bytes. Keep in mind though that every allocated object consumes a few bytes of invisible bookkeeping data used by the runtime's implementation of `malloc()`, and there may be other hidden things floating around in the system, like some objects allocated by libraries. Also remember that on Arduino, SRAM is shared by stack and heap.

Now let's say you have 8KB of heap space and you allocate a lot of stuff, then deallocate a lot of stuff, leaving exactly 3 small objects allocated. This will divide your heap into 4 regions. The average size will be just under 2KB and so no matter how unlucky you are, one or more of the regions will be *at least* that size. So you should be able to allocate one large object of around 2KB, or, allocate hundreds of small objects, or allocate one object and keep resizing it anywhere up to 2KB. If you then free everything except for 3 small objects, you will be back in the same situation: you are guaranteed a region of at least 2KB.

There are two noteworthy conclusions:
 * If the maximum number of items that will ever be allocated at a time is `n`, and their maximum size is `s`, and your heap size is at least `(2n+1) × (s+4)`, you will never have a fragmentation problem. (3 is an architecture-dependent fudge factor to cover `malloc` bookkeeping and padding issues.)
 * If there are "checkpoints" in your code where only a few objects are allocated, this makes it easier to reason about what can happen between these checkpoints.

> Are there any tools to measure / alert / help us know how close we are to fall off that cliff?

Not for Arduino that I know of. The problem is, a program susceptible to severe fragmentation may only display signs for short periods once every few days or something.

The easiest technique you can use is to consume say 30% of your memory with `malloc()` at the start of your program to put more heap pressure on it, and see if it still works. This isn't guaranteed to bring the problems out of the woodwork, but it greatly boosts the chances that you will see something.

You can also write a function to try to allocate the largest objects possible over and over, slowly reducing the size, and see to what extent you are prevented from allocating large objects but can allocate small ones. I was going to post one but I decided it would be of limited benefit.

If you really want to see what is going on with your heap you can [look at the source of your `malloc()` implementation][1] and inspect its data structures from within your program. In this case it seems to be as simple as putting this at the start of your code

    struct __freelist {
      size_t sz;
      struct __freelist *nx;
    };
    extern struct __freelist *__flp;

and then you can traverse the contents of the [freelist][2] using `__flp`.

  [1]: https://github.com/XMegaForArduino/arduino/blob/master/cores/xmega/avr-libc/malloc.c
  [2]: https://en.wikipedia.org/wiki/Free_list


body:
As you already got good answers to most of your questions, I will try
to cover here only this one:

> Is it possible to quantify the fragmentation and get a feel of what's  safe and when it becomes risky?

A quick Web search for “Arduino free memory” finds a few code snippets
that can be used to measure, at run time, the amount of free memory:

* [Available Memory][], in the Arduino Playground, only works on AVR. It
  measures  the total amount of available RAM, including the holes in
  the heap.

* [Measuring Memory Usage][], an Adafruit tutorial, shows some portable
  (AVR and ARM) code that measures the available RAM between the heap
  and the stack. This does _not_ include the holes in the heap.

If you compare the AVR versions of these two code snippets, you can see
the difference is in the `freeListSize()` function of the Playground
version. This function returns the total memory residing in heap holes,
which could be a measure of the heap fragmentation.

The function is AVR-specific, but then AVR is where heap fragmentation
is most worrisome.

[Available Memory]: https://playground.arduino.cc/Code/AvailableMemory/
[Measuring Memory Usage]: https://learn.adafruit.com/memories-of-an-arduino/measuring-free-memory


body:
I'm not an Arduino programmer, but I am a C programmer.  And the problem of string types in C -- or, rather, the *absence* of a first-class string type in C -- is an old but important one.

The fundamental problem is this.  In C, you can say things like

    int a, b, c, d, f();
    a = b + c;
    d = f();

And you can say things like

    float q, r, s, t();
    q = r / s + t();

But you can *not* say

    string x, y, z();
    x = y + z();

C has no first-class string type.  In pure C, if you want to manipulate strings, you have to use some combination of `char []` arrays and `char *` pointers.  You have to remember to allocate enough memory to hold the strings you're working with today.  In many cases you can't assign strings; you may have to call `strcpy` or the like.  In most cases you can't directly compare strings; you usually have to call `strcmp` or the like.  This can all be a real nuisance, and if you get the details wrong, you get strange bugs and crashes.

So, especially if you're a beginning or casual programmer, It Would Be Nice if C had a true, first-class string type.  (And of course C++ does have such a type.)

But there's a very good reason that plain C doesn't have such a type.  Manipulating strings is just plain harder than manipulating ints or floats.  The reason it's harder is precisely because they're variable-length, and potentially rather large.  Under C's low-level philosophy, the best person to make good tradeoffs when it comes to deciding how to handle a particular program's strings is that program's author, *not* the compiler or library writer.

You can write a decently good, decently efficient, high-level, first-class string type.  *But*, it's never going to be *as* efficient, for every problem, as handcrafted `char []` and `char **` code would be.  Also, if there are a bunch of rules for how to use a first-class string type efficiently, avoiding fragmentation and the like, those rules are probably going to end up being almost as complicated as the rules for using `char []` and `char *` correctly -- but the whole point of introducing the first-class string type was so that programmers *wouldn't* have to worry about those low-level details all the time!  It's really rather a pretty pickle.

So when someone says, "you shouldn't use that high-level string type, it's wasteful and inefficient", the question to ask is, is it *unacceptably* wasteful or inefficient?

Once upon a time, people said we shouldn't use compiled languages, since they're wasteful and inefficient.  Those people thought we should all write everything in assembly language.  (And there are still a few people who say this.)  Most of the time, though, we've discovered that compiled code is adequately efficient, and its other advantages more than make up for any slight lingering inefficiencies.

And the question for C strings versus Strings is almost perfectly equivalent.  If your program is making significant use of strings, expending a large fraction of its time or a large fraction of the available memory towards them, the inefficiencies of Strings might well be unacceptable.  If there are relatively few strings, however, the convenience to the programmer of using a high-level String type (along with the absence of bugs) might be well worth it, and the costs might be inconsequential.

But there's no one right answer to the question of "Do or don't use Strings", because it's a subjective question, and different people under different circumstances will legitimately come to different conclusions.


body:
I'd like to answer your question without discussing the more technical side. This has been admirably covered by my learned colleagues in their own answers. I am going to address the cost-benefit side of using String.

Certainly, in the short term, it is almost certainly faster and easier to use String than to allocate buffers of characters, keeping track of how full they are, appending to the end of them, and so on.

For example, to read serial input, this is easy:

    String inputBuffer;

    void loop()
      {
      while (Serial.available () > 0)
        inputBuffer += Serial.read ();

      if (inputBuffer == "something")
        doSomething ();
      }  // end of loop

This, by the way, is the very sort of code that is likely to cause heap fragmentation and a crash. :)

So, you may well save an hour or two of coding by using the String class. So far, so good. You are ahead.

Then you start testing. Things go well for a while, but then after your code runs for an hour it mysteriously crashes, or probably, hangs. Your device stops doing what it is supposed to do, and you start looking for bugs. There is nothing *obviously* wrong, so you spend quite a bit of time trying to solve the issue. Heap fragmentation doesn't jump out and slap you in the face like, say, forgetting to add one variable to another.

So you look over the code, maybe post a question on Stack Exchange, maybe ask friends, maybe ask your teacher (where appropriate). Soon enough, time is mounting. You spend an hour debugging, two hours, four hours, and soon you have spent eight hours on it. Now you have wasted all the benefit you got from using the "easy" String class. Not only that, you are way behind, compared to allocating a fixed-size buffer and managing putting data into it yourself.

Sooner or later you identify that heap fragmentation is the culprit, and have to rewrite it. In other words, you eventually have to stop using the String class. So the whole episode has been a waste of time.

Certainly this won't always happen, and for the occasional use of fixed-length String objects, there won't be an issue. But if you look at the conditions mentioned in the other answers, you can see that it is easier, in fact, to "just don't use String" than to use them in very careful ways, and hope that your project doesn't break today, tomorrow, next week, or after three months "in the field".

>  why should I not use String if it makes my work so much easier?

Certainly you should, if it makes your work easier, *and if it doesn't crash*.

>  does anyone know when a program will crash?

No, probably not. If you are "lucky" it will crash soon after you start it, and you will at least know you have a problem. If you are unlucky your fish feeder will stop feeding your fish two weeks into your holiday and they will die.


body:
Mega point is: don't use String (or anything else that uses the heap) inside interrupts - even with objects created outside the interrupt. the underlying memory allocation functions cannot deal with it and you've got a good chance something will go boom.

As for the rest, so much of this is dependant on implementation

Nick's answer with the input buffer yes will crash, he never clears it! (j/k)
But even if he did after matching with something, i.e.

          if (inputBuffer == "something") {
                inputBuffer="";
                doSomething ();
          }

after we've hit this there will be no more (possible) fragmenting to do with this code, as the implementation for String on the copy (or a concatenation) there *does not reallocate the memory buffer unless it is too small*. So as we go round this whole loop after the first time, no heap allocations will happen.

We could also remove any reallocations during the initial building of the 'something' string in the inputBuffer by allocating enough space right at the beginning of the code with

        inputBuffer.reserve(9);

where 9 is the length of the string 'something' (reserve will add an extra byte on the buffer for the string terminator)

You can also use this to reserve space for doing multiple concatenations . Anything above 1 concat / += will save time because of not multiply reallocating space, plus stop the fragmentation.

        int newSize=a.length()+b.length()+c.length();
        a.reserve(newSize); // only memory realloc happens here
        a.concat(b);
        a.concat(c);

Similarly you could create a much bigger buffer to briefly handle something you're not sure the size of (say, reserve 512 bytes) but beware! because of the point above (.reserve() does not reallocate the buffer unless the requested size is larger) you are stuck with that buffer *until the string object is destroyed by going out of scope or being explicitly deleted*. Global objects are stuck with it. So if you need a global object that could get bigger or smaller, make it a pointer to a String then use new/delete as required.

Also we need to consider object lifetime. Even if you use a bunch of String objects in a function, if they are all destroyed at the end, and you haven't created any other heap objects within that function, when you have left and all the Strings are auto destroyed there should be no impact on the heap, it should return to its previous state as the memory is reclaimed

If you are creating String objects on the heap (via new) though it does compound any fragmentation problems you may have in your code anyway as you end up with 2 heap items, the String wrapper object and the data itself. If you're just using a local or global variable the wrapper won't be in the heap, either in global memory or on the stack.


message:
Battery voltage measurement with voltage divider

I am using the following circuit to measure the Li-ion 3.7V battery capacity.

[![Setup for 3.7V Batteries][1]][1]

*Figure 1 – Schematic for 3.7 V batteries.*

This setup works fine for the 3.7V batteries.

To be able to measure 9V batteries, I modified the circuit with a voltage divider so that the Arduino sees max 5v at the analog input. However Arduino reports 0V. I have measured the output of voltage divider with a DMM and it shows 5V. I wonder why doesn't Arduino report the correct voltage. Could you please help me fix it?

[![Modified schematic for 9 V batteries which doesn't work][2]][2]

*Figure 2 – Modified schematic for 9 V batteries which doesn't work.*

My code:

```cpp
#include "LCD5110_Graph.h"
LCD5110 myGLCD(5, 6, 7, 9, 8); // Setup Nokia 5110 Screen SCLK/CLK=5, DIN/MOSI/DATA=6, DC/CS=7, RST=9 Chip Select/CE/SCE=8,
extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];

#define gatePin 10
#define highPin A0
#define lowPin A1

boolean finished = false;
int printStart = 0;
int interval = 5000; // Interval (ms) between measurements

float mAh = 0.0;
float shuntRes = 1.0; // In Ohms – Shunt resistor resistance
float voltRef = 4.71; // Reference voltage
float current = 0.0;
float battVolt = 0.0;
float shuntVolt = 0.0;
float battLow = 2.9;

unsigned long previousMillis = 0;
unsigned long millisPassed = 0;

void setup()
{
 Serial.begin(9600);
 Serial.println("Battery Capacity Checker v1.1");
 Serial.println("battVolt current mAh");

 pinMode(gatePin, OUTPUT);
 digitalWrite(gatePin, LOW);

 myGLCD.InitLCD(); // initialize LCD with default contrast of 70
 myGLCD.setContrast(68);
 myGLCD.setFont(SmallFont); // Set default font size. tinyFont 4×6, smallFont 6×8, mediumNumber 12×16, bigNumbers 14×24
 myGLCD.clrScr();

 myGLCD.print("Battery", CENTER, 0);
 myGLCD.print("Check", CENTER, 12);
 myGLCD.print("Please Wait", CENTER, 24);
 myGLCD.print("AdamWelch.Uk", 8, 40);
 myGLCD.update();
 delay(2000);
 myGLCD.clrScr();
}

void loop()
{
 battVolt = analogRead(highPin) * voltRef / 1024.0;
 shuntVolt = analogRead(lowPin) * voltRef / 1024.0;

 if (battVolt >= battLow && finished == false)
 {
  digitalWrite(gatePin, HIGH);
  millisPassed = millis() – previousMillis;
  current = (battVolt – shuntVolt) / shuntRes;
  mAh = mAh + (current * 1000.0) * (millisPassed / 3600000.0);
  previousMillis = millis();

  myGLCD.clrScr();
  myGLCD.print("Discharge", CENTER, 0);
  myGLCD.print("Voltage:", 0, 10);
  myGLCD.printNumF(battVolt, 2, 50, 10);
  myGLCD.print("v", 77, 10);
  myGLCD.print("Current:", 0, 20);
  myGLCD.printNumF(current, 2, 50, 20);
  myGLCD.print("a", 77, 20);
  myGLCD.printNumI(mAh, 30, 30);
  myGLCD.print("mAh", 65, 30);
  myGLCD.print("Running", CENTER, 40);
  myGLCD.update();

  Serial.print(battVolt);
  Serial.print("\t");
  Serial.print(current);
  Serial.print("\t");
  Serial.println(mAh);

  delay(interval);
 }
 if (battVolt < battLow)
 {
  digitalWrite(gatePin, LOW);

  finished = true;

  if (mAh < 10)
  {
   printStart = 40;
  }
  else if (mAh < 100)
  {
   printStart = 30;
  }
  else if (mAh < 1000)
  {
   printStart = 24;
  }
  else if (mAh < 10000)
  {
   printStart = 14;
  }
  else
  {
   printStart = 0;
  }

  myGLCD.clrScr();
  myGLCD.print("Discharge", CENTER, 0);
  myGLCD.print("Voltage:", 0, 10);
  myGLCD.printNumF(battVolt, 2, 50, 10);
  myGLCD.print("v", 77, 10);
  myGLCD.setFont(MediumNumbers);
  myGLCD.printNumI(mAh, printStart, 21);
  myGLCD.setFont(SmallFont);
  myGLCD.print("mAh", 65, 30);
  myGLCD.print("Complete", CENTER, 40);
  myGLCD.update();

  delay(interval * 2);
 }
}
```

Circuit with modifications

[![Schematic for 9 V Batteries][3]][3]

*Figure 3 – Schematic for 9 V batteries.*

  [1]: https://i.stack.imgur.com/hcKtR.png
  [2]: https://i.stack.imgur.com/uJHVe.png
  [3]: https://i.stack.imgur.com/Iowen.png

body:
The problem comes because you are powering your load through the voltage divider you use for reading your battery voltage.

You cannot do high-side current reading like that with a voltage higher than the ADC voltage. Instead you need to do the current sensing *before* your voltage divider and *then* divide that result down again.

Your circuit should look more like:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/v81u4.png)

<!-- End schematic -->


message:
Multiple I2C devices connected to one Arduino Uno?

Is it possible to connect more than one I2C device to an Arduino Uno? I know that the SCL and SDA pins are on analog pins A4 and A5 respectively, but there are also two pins labeled SCL and SDA located next to the AREF pin on the other side of the board. Does that mean I can connect multiple devices to the same board and, if so, how?

For context, I'm currently working on creating a robotic arm that matches its movements to the movements of my arm (I believe this is called a telepresence robot). To do so, I wanted to use a couple of IMUs (specifically the MPU-6050) to record the movements of my wrist and shoulder. Using the [TinyMPU6050][1] library by Gabriel Milan, I've already been able to establish communication with one IMU, but I'm struggling with the second one. I'm already communicating with the arm via the Uno's SPI interface so I can't use that to communicate with a second IMU, although I know it's possible.

I know that similar questions have been asked before, but none of the questions I could find had the exact answers that I needed, so I thought I would ask anyway. This code that I currently have works for one IMU, but I don't know where to begin to add a second one (if it's even possible). Any help that I can get would be greatly appreciated. Cheers!

  [1]: https://github.com/gabriel-milan/TinyMPU6050

```
#include <TinyMPU6050.h>

MPU6050 IMU_1(Wire);

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

  //initializing and calibrating `IMU_1`
  IMU_1.Initialize();
  Serial.println("Calibrating...");
  IMU_1.Calibrate();
  Serial.println("Calibrated");

  while (!Serial) {
    //empty while loop
  }
}

void loop() {
  IMU_1.execute();
  Serial.println();
  Serial.print("X angle = ");
  Serial.println(IMU_1.GetAngX());
  Serial.print("Y angle = ");
  Serial.println(IMU_1.GetAngY());
  Serial.print("Z angle = ");
  Serial.println(IMU_1.GetAngZ());

  delay(1000);
}
```

body:
I2C is a *multi-drop bus*. That means that one set of I2C pins are *designed* to have multiple devices on it *as long as each device has a unique address*.

On an Uno the discrete I2C pins and the A4/A5 I2C pins are the same pins. The discrete pins are an attempt to provide a cross-platform standard location for the I2C signals for shields.


message:
How do I recreate the Pong game with two pots and the map function?

I am working on a project for my brothers and anyone else who is interested in playing some LED Pong. I was just stuck on the software part. I don't really know what to do. But, I have an idea: I want to use the map() function to make my life easier, however, I am not sure how to use the map function with the Dot Matrix. All help would be appreciated. All of the stuff came in [this kit.][1]

Here is the test code:

    #include <LedControl.h>

    int DIN = 2;
    int CS =  3;
    int CLK = 4;

    const int playerOnePin = A0;
    const int playerTwoPin = A1;

    int playerOneValue;
    int playerOneValue2;
    int playerTwoValue;
    int playerTwoValue2;

    LedControl lc = LedControl(DIN, CLK, CS, 0);

    void setup() {

      lc.shutdown(0, false);      //The MAX72XX is in power-saving mode on startup
      lc.setIntensity(0, 15);      // Set the brightness to maximum value
      lc.clearDisplay(0);          // and clear the display

      pinMode(playerOnePin, INPUT);
      pinMode(playerTwoPin, INPUT);

    }

    void loop() {

      byte a[8] = {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
      printByte(a);

    }

    void printByte(byte character []) {

      int i = 0;
      for (i = 0; i < 8; i++)
      {
        lc.setRow(0, i, character[i]);
      }
    }

    void readPot() {

      playerOneValue = analogRead(A0);

      playerOneValue2 = map(playerOneValue, 0, 1023, 0, 180);
    }

Here is the other code:

    #include <LedControl.h>

    int DIN = 2;
    int CS =  3;
    int CLK = 4;

    byte displayImage[8] =     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    // considering a 2d co-ordinate system with origin (0,0) at bottom left corner
    int ballX = 3; //X position
    int ballY = 7; //Y position - top
    int speedX = 0; // no X movement, can be -1, 0 or 1
    int speedY = -1; // downward Y movement, can be -1, 0 or 1
    int paddleX = 4; // X position of center of paddle - can be 1 to 6. Paddle width is 3
    int score = 0;

    LedControl lc = LedControl(DIN, CLK, CS, 0);

    void setup() {
      pinMode (A0, INPUT);
      pinMode (A1, INPUT);
      lc.shutdown(0, false);      // Keep MAX72XX awake
      lc.setIntensity(0, 15);     // Set the brightness to maximum value
      lc.clearDisplay(0);         // and clear the display
    }

    void loop() {
      // update ball position
      ballX = ballX + speedX;
      ballY = ballY + speedY;

      // check for ball interaction with walls
      if (ballX == 0 || ballX == 7) {
        speedX = speedX * -1; // bouncing off walls in horizontal direction
      }

      // bouncing off ceiling
      if (ballY == 7) {
        speedY = speedY * -1; // bouncing off the ceiling
      }

      // bouncing off the paddle
      if (ballY == 0 && ballX >= (paddleX - 1) && ballX <= (paddleX + 1)) {
        speedY = speedY * -1;
        score++;    // player earns a point
      }

      // going past the paddle
      if (ballY == 0 && ballX < (paddleX - 1) && ballX > (paddleX + 1)) {
        // going past the paddle - player is out
        Serial.println(); Serial.print("Score: "); Serial.println(score);
        for (int i = 0; i < 8; i++) {
          displayImage[i] = 0x00;
        }
        displayImage[3] = 0xFF; displayImage[4] = 0xFF; // show a line
        renderByte(displayImage);
        while (1); // Freeze
      }
      // clearing the image variable
      for (int i = 0; i < 8; i++) {
        displayImage[i] = 0x00;
      }

      // generating new image
      addPixel(ballX, ballY); // adding the ball position to image
      addPixel(paddleX - 1, 0); addPixel(paddleX, 0); addPixel(paddleX + 1, 0);
      // adding paddle position to image
      renderByte(displayImage); // show the generated image

      // handling paddle control
      if (analogRead(A0) && paddleX > 0) {
        paddleX = paddleX - 1; // move paddle left
      }

      if (analogRead(A1) && paddleX < 7) {
        paddleX = paddleX + 1; // move paddle right
      }

      delay(200);
    }

    void addPixel(int xVal, int yVal) {
      int newRowval = 2 ^ (7 - xVal);
      int rowVal = displayImage[7 - yVal];
      displayImage[7 - yVal] = rowVal || newRowval;  // inserting a 1 at the required pixel
    }

    void renderByte(byte image [])
    {
      int i = 0;
      for (i = 0; i < 8; i++)
      {
        lc.setRow(0, i, image[i]);
      }
    }

Here is the picture of the wiring and the schematic:

[![This is the wiring picture][2]][2]

[![Wiring Pic][3]][3]

[![Wiring Pic][4]][4]

[![Wiring Pic][5]][5]

[![Schematic][6]][6]

  [1]: https://www.amazon.com/EL-KIT-008-Project-Complete-Ultimate-TUTORIAL/dp/B01EWNUUUA/ref=sr_1_1_sspa?dchild=1&keywords=arduino mega kit&qid=1626207537&sr=8-1-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUExR1NEMVNXUkpRS0ZDJmVuY3J5cHRlZElkPUEwODgxNjc5MzA2V1U5RFFLVEpBSSZlbmNyeXB0ZWRBZElkPUEwNTQyNzgzMllKVEdLM0pFNURRViZ3aWRnZXROYW1lPXNwX2F0ZiZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU=
  [2]: https://i.stack.imgur.com/NztGE.jpg
  [3]: https://i.stack.imgur.com/t6lbL.jpg
  [4]: https://i.stack.imgur.com/LsFrd.jpg
  [5]: https://i.stack.imgur.com/t9nGu.jpg
  [6]: https://i.stack.imgur.com/LJvnT.jpg

body:
First figure out the min and max values that paddleX can have.  I assume if the paddle is two dots wide then its min,max will be 0,6   Then figure out the min and max of your pot, typically 0,1023 for a a 10 bit adc.  Now to map your pot value to paddleX value you'd use the command :

    paddleX = map(analogRead(A0),0,1023,0,6);

here is the map documentation : https://www.arduino.cc/reference/en/language/functions/math/map/


message:
How does the FireBeetle ESP32 regulate to 3.3v? (schematic provided)

The [FireBeetle ESP32][1] advertises an input voltage of 3.3v-5v, with an operating voltage of 3.3v.

I tested this with an 18650 lithium-ion battery and can confirm this is true. For 3.3V < Vbat < 4.2V, there is a consistent ~3.295 volts at the 3V3 pin. For Vbat < 3.3V, 3V3 drops slightly under Vbat (approx. -.02V).

I found this odd because the onboard RT9080-33GJ5 regulator has a dropout of about 0.2V to 0.3V, so theoretically the output voltage should drop off steeply for Vbat < 3.6V.

Looking at the [schematic][2], I was unable to figure out exactly how this board is able to regulate to 3.3 volts with essentially no dropout. Is it using some sort of buck converter that isn't mentioned in the schematic, or some other clever circuit?

Any help understanding would be much appreciated!

  [1]: https://www.dfrobot.com/product-1590.html
  [2]: https://raw.githubusercontent.com/DFRobot/Wiki/master/DFR0478/[DFR0478]FireBeetle Board-ESP32(V4.0)生产检查图.PDF

body: Answered my own question - I didn't realize that dropout voltage essentially goes to 0 for this regulator when current consumption is low. Pretty neat for low current applications with the ESP32.


message:
Arduino Motor Control at a Specific Time

[![enter image description here][1]][1]Hello. Currently I'm working on creating an automatic dog food dispenser. I'm using a Arduino Uno R3, an L298N stepper driver, a DS1307 RTC breakout board, a Nema 17 stepper motor, and a breadboard to disperse the power to each board. I'm using a 9V battery to power it temporarily. I've tested motor control without it being determined by the current time and it works perfectly however when I have the motor run at a specific time (4:45 and 6:45 in the code) the motor doesn't move. How can I move the motor at these specific times?

    #include <RTClib.h>
    #include <Stepper.h>
    #include <SoftwareSerial.h>

    RTC_DS1307 rtc;

    Stepper myStepper(200 , 9 , 10 , 11 , 12);

    void setup() {
      Serial.begin(9600);
      rtc.adjust(DateTime(2021 , 7 , 14 , 4 , 44 , 0));
      myStepper.setSpeed(20);
    }

    void loop() {

      DateTime now = rtc.now();

      if ((now.hour() == 4 and now.minute() == 45) or (now.hour() == 6 and now.minute() == 45)) {
          Serial.println("testing");
          myStepper.step(10000);
          delay(1000);

    }

    }

  [1]: https://i.stack.imgur.com/PS2m6.jpg

body: You are pushing the limit of the L298N, probably will exceed it. A typical stepper motor like a NEMA 17 is probably rated at voltage of about 2.8 Volts and a maximum current of 1.68 Amps. This basically means if you hook it up to 2.8 Volts it will draw 1.68 Amps. If you try to run it at a higher voltage it will draw more current and get excessively hot. Driver Model: L298N has a Motor Supply Current (Maximum): 2A, Logic Voltage: 5V, Driver Voltage: 5-35V. The motor was rated at about 2.8V, powering it with more will very quickly exceed your bridge capacity. The Arduino will give you 5V and 3.3V but using either to power your motor will probably destroy the Arduino. The Arduino a power supply it is NOT! I suggest you use a seperate power supply for the motor. If you power the Arduino via Vin and use a buck converter from the 12V it should work fine.


body: I’m new at this but looks to me like your rtc is uses i2c comms.  I don’t see that you’ve included wire.h or issued the wire.begin to initiate communication between the rtc and arduino.  See other rtc examples and good luck!


message:
Incorrect values arriving from Arduino to RPi over serial communication

I am trying to write four values relating to energy (current, power, energy, and peak demand) via a SoftwareSerial connection from my Arduino UNO to my Raspberry Pi 4.  However, two things are occurring:

1.  All of the values should be different, but they are printing to the RPi terminal as if they're identical.

2.  It seems as if the values I'm writing are merging together(?), creating a nonsense value.  For example, if the values that I'm sending are 0.24, 28, 0.05, and 71, they appear in the RPI terminal looking like this:

Current:  54543878

Power:  54543878

Energy:  54543878

Peak Power:  54543878

This is a snip of my Arduino code that writes to the Bluetooth serial connection (uses HC-06):

      bluetoothSerial.write(RMSCurrent);
      bluetoothSerial.write(RMSPower);
      bluetoothSerial.write(kilos);
      bluetoothSerial.write(peakPower);

This is a snip of the Python script that receives it:

    while 1:
 try:
  received_data = bluetoothSocket.recv(1024)
  RMSCurrent = int.from_bytes(received_data,byteorder='big')
  RMSPower = int.from_bytes(received_data,byteorder='big')
  kilos = int.from_bytes(received_data,byteorder='big')
  peakPower = int.from_bytes(received_data,byteorder='big')

  print("Current (A): %d" % RMSCurrent)
  print("Power (W): %d" % RMSPower)
  print("Energy (kWh): %d" % kilos)
  print("Peak Demand: %d" % peakPower)

 except KeyboardInterrupt:
  print("keyboard interrupt detected")
  break
    bluetoothSocket.close()

Does anyone have any ideas of what is going on?  Two of my values are floats and two are integers.  I've tried to fix this for the past 12 hours, but to no avail.

body:
You will save yourself a lot of headaches by sending the data in ASCII
instead of binary:

```c++
bluetoothSerial.print("RMSCurrent: ");
bluetoothSerial.println(RMSCurrent);
```

Of course, you will then have to _parse_ the data stream on the Python
side.

If you really want to send binary data, then be aware that the `write()`
method you are using is intended for sending single bytes. Every number
you `write()` is converted to an integer (truncated if it's a float),
reduced modulo 256 to the range [0, 255], then sent as a single
byte. You can loose quite a bit of information in this process.

To send a binary object larger than a byte, you have to use an overload
of `write()` that takes both a pointer (the address of the object) and a
number of bytes to send. For example:

```c++
bluetoothSerial.write((uint8_t *) &RMSCurrent, sizeof RMSCurrent);
```

But then, you have to be aware that some numeric types do not have the
same binary representation on the Arduino and on the Pi. For instance:

* an `int` is 2 bytes on the Arduino and 4 bytes on the Pi
* a `double` is 4 bytes on the Arduino and 8 bytes on the Pi

I recommend you only use fixed-size integer types (`uint16_t` and such)
and `float`.

Also, be aware that the Arduino is little-endian, like the Pi, and
unlike what your Python code currently assumes.

Oh, and the serial link does not have a notion of data packets. If there
happens to be some leftover crap in the serial buffer when you start
your Python program, it will get out of sync with the Arduino, and you
will only read garbage. There are ways around this problem (search for
“packet framing”) but they add quite a bit of complexity.

As I said, you will save yourself a lot of headaches by sending the data
in ASCII instead of binary.


message:
Decoding of data received using the WL-101 433 MHz radio module

Good afternoon! This question is still relevant to me. I use the receiver module in conjunction with arduino. I want to use my own transfer protocol and now I need to accept it. I tried to use various libraries, but all without success. I need to somehow select a sequence of pulses and then determine their values (zero or one) by the duration of the pulses.
But first, I need to determine the beginning of the signal from the preamble (12 pulses at the beginning). I wrote a program that draws a graph where you can see the entire sequence.
Is it possible to define this preamble without using libraries, for example, to make a cycle that will measure the length of the pulses, and there are 12 times the duration of the pulses will be the same, then this is the preamble, followed by digital data.

    #define IN_PIN 2
    void setup()
    {
      Serial.begin(115200);
    }

    void loop()
    {
      bool s = digitalRead(IN_PIN);
      Serial.println(s);
    }

[![enter image description here][2]][2]

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/1TWvp.jpg
  [2]: https://i.stack.imgur.com/BNVAu.png

body:
It is not working because of:

**SPEED**

Consider the frequency of the 433Mhz device vs. the speed of the serial monitor. The device sends signals with pulse width in the range of tens of microseconds while the serial monitor can't display that fast.

Your code should analyze the signals, clean the noise (the output of the device is very noisy) and figure out the protocol. All that is done by dedicated libraries such as [rc-switch][1] which is very extensive and robust compared to just reading a pin and plotting the output.

**DIGITAL**

The recover device is outputting a digital pulse which based on it's pulse width changes one can figure out the sequence of numbers sent by the remote control. Each such ASK protocol has it's timing characteristics which you should follow in order to decode the code.

If you want to experiment with that vs. using a ready made library you should start with a code similar to the example below.

    void setup() {
      Serial.begin(6000000);
      attachInterrupt(digitalPinToInterrupt(1), handleInterrupt, CHANGE);
    }

    void loop() {
    }

    void handleInterrupt() {
      bool s = digitalRead(1);
      Serial.println(s);
    }

Just pay attention to the timing issue, this code will show a lot of data but not necessarily (almost for sure) not all the data, but you can avoid the serial print and use the data for analysis.

  [1]: https://github.com/sui77/rc-switch


message:
Arduino Uno Esp8266 AT commands

I am trying to send AT commands to esp-01 through serial monitor I have uploaded a blank sketch to Arduino , whatever command I send to ESP I get reply ERROR.
After reconnecting esp-01 I got some garbage vales then ready.
Can anyone help me what I am doing wrong.
This is what I got on serial monitor
 [![this is what I am getting on serial monitor][1]][1]

These are the connections I am using, I tried to use voltage divider but after using voltage divider, Esp's blue led turned on and nothing happened so I used just used the resistors in series between TX and TX of both devices

[![CONNECTIONS ][2]][2]

This is the voltage divider circuit I was using(that didn't worked)

[![voltage divider circuit][3]][3]

  [1]: https://i.stack.imgur.com/rI64i.png
  [2]: https://i.stack.imgur.com/rmqRk.png
  [3]: https://i.stack.imgur.com/h81d9.png

body:
The hardware serial, pins 1 and 2, are used by the Arduino to communicate to the USB adapter to your computer.  When you connect another device to them, it interferes with the communication between your computer and the Arduino.

The solution is to connect the ESP-01 to another set of pins and use the `SoftwareSerial` library to create a second serial port for it.  The code then needs to listen on both serial ports and move data between them.

Also, you need to use the voltage divider or you risk burning out the input pin.  To make the voltage divider, connect the Arduino output to the top of the divider and the ESP-01 to the middle.  You appear to have those reversed in your schematic.