body:
In the instructables code he's using a `float` because he wants to scale the value to a range of ±2g. The values the accelerometer gives are not the actual values but, like the Arduino's ADC, a representation of the value using a range.  By dividing that representation by 16384 you get the actual G value, which is a decimal value.

That value can be more useful than the raw data.

As for that other snippet of code you provide, it cannot work. Not only does it use global variables that don't exist, but it returns a value from a `void` function which cannot happen. I don't know quite what it hopes to achieve.


sender: user

message:
Safe to power LED strip via ESP32 GPIO

I want to rewire a battery powered LED strip (as shown in the picture below) to power via an ESP32's GPIO pin. I have a ESP32 NodeMCU Development Board, powered via USB.

The LED strip has specified 3,2V/20mA for the 100 LEDs. It originally uses three AA batteries. From what I've gathered the ESP32 should have a max current output of 40mA.

Other than the LED strip, the ESP32 uses WiFi and addresses a DHT22.

The goal would be to turn the LEDs on/off via a GPIO, for example:

    pinMode(4, OUTPUT);
    digitalWrite(4, HIGH);
    digitalWrite(4, LOW);

[![LED strip][1]][1]

Would it be safe to power the LED strip via a GPIO pin?

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

sender: assistant

body:
Quick answer is probably not.  Why?  The numbers don't add up:

> ...3,2V/20mA for the 100 LEDs...

From [here][1] we find this comment:

> Most common LED’s require a forward operating voltage of between
> approximately 1.2 to 3.6 volts with a forward current rating of about
> 10 to 30 mA, with 12 to 20 mA being the most common range.

(Actually there are [low current LED on the market][2] now that only need about 3mA to operate.  Let us assume this is what you have for our calculations.)

So, given the above is true, and if your string of LEDs were all in parallel and had average specifications, we calculate the current and voltage of the string of 100 LEDs:

    Current: 100 x 3mA = 300mA or 0.3 Amps
    Voltage: About 2 Volts.

(Note: When designing with LED you should always refer to that LED's specification.  The above 30mA and 2 Volts is only a guess.)

So, even if your LEDs are of the low current type, you can see a string of 100 such LED in parallel exceeds the initial expected current for the entire string of 100 LEDs.

This assumes the LEDs are in parallel and the power source is a constant voltage.  What if the LEDs are in series?  Then you would need a constant current power source.  Again let's assume the individual LED specifications are 2 Volts and 3 mA.  Now the calculations might look like this:

    Current: About 3mA.
    Voltage: 100 x 2 Volts = 200 Volts

Obviously the voltage far exceeds the capability of three 1.5 Volt batteries.

Ah!  [Bigclivedotcom gives us some insight in his 2017 youtube video about repairing several variations of low voltage LED strings][3]. The 3 different strings he uses in his video address how these LED strings can be made such that different voltage and current sources can be used to power them.

In conclusion it is likely your string of LED will require more current to power then a GPIO pin who's maximum current rating is only 40mA can provide safely.

  [1]: https://www.electronics-tutorials.ws/diode/diode_8.html
  [2]: https://www.digikey.com/en/product-highlight/s/sunled/ultra-low-current-leds
  [3]: https://www.youtube.com/watch?v=DoRbHYJAwis


message:
Can I wire LEDs without resistor with an Arduino like this?

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

  [1]: https://i.stack.imgur.com/P9Ulq.png
There are four red LEDs and an Arduino in the picture. Each LED has a forward voltage of 2 V. My friend says that just `digitalWrite(9,HIGH)` will make the LEDs light without resistor and they won't be burnt. Is this true?

body:
I am assuming you only have 5VDC available. Your friend is almost correct, it will work for a while however in the long run it will probably fail unless you are one of the lucky ones. What is the Vf (forward voltage drop) range of the LEDS (you state 2V), and are they matched by pairs, if not they will not illuminate evenly. You are forcing the arduino to output its maximum on port D9. I believe the current will not be within the microprocessor specifications. You are assuming a LED is a voltage device, it is not it is a current device. A resistor or constant current source is normally used to drive LEDs.  The LED driving circuit must provide sufficient current to light the LED at the required brightness, but must limit the current to prevent damaging the LED and driver. Typically, the forward voltage (Vf) of an LED is between 1.8 and 3.3 volts. It varies by the color of the LED. A red LED typically drops around 1.7 to 2.0 volts, but since both voltage drop and light frequency increase with band gap, a blue LED may drop around 3 to 3.3 volts. across an LED is approximately constant over a wide range but can vary from LED to LED.

 LEDs are diodes and have a


body:
Depending on the LEDs, it might or it might not, who knows?
You'll be both safe and in control by adding a small resistor in series (either with each individual LED or, if the LED pairs are balanced, with the whole LED circuit). The resistor value depends on the LEDs and the Arduino's supply voltage.


message:
Arduino DUE wheel encoder

I have an Arduino due, I am trying to keep track of ticks on two wheel encoders, polling in an infinite loop results in terrible performance. Have any suggestions?

It looks like the due might have an internal counter but I don't know how to use it, is there a library?

body:
You can use an interrupt handler to measure frequency. Works quite well.

```cpp
volatile int32_t _ticks = 0;
public void FrequencyIsr()
{
    _ticks++;
}

// Add this to setup()
// Mode can be FALLING, RISING or CHANGE
attachInterrupt(digitalPinToInterrupt(pin), FrequencyIsr, mode);

// Add this to loop()
int32_t currentTime = millis();
// Clear the interrupt flag, so that we can read out the counter
noInterrupts();
int32_t ticks = _ticks;
interrupts();
// and then calculate the amount of ticks since the last update (if you need the speed)
int32_t timeDelta = currentTime - _lastTime;
int32_t tickDelta = ticks - _lastTicks;
double ticksPerMs = (double)tickDelta/timeDelta;
_lastTime = currentTime;
_lastTicks = ticks;
```


message:
BLE library for Beetle Bluno BLE with AVR architecture (Atmega328)

When I try to `#include <ArduinoBLE.h>` in my Arduino program, I get the error:

>WARNING: library ArduinoBLE claims to run on samd, megaavr, mbed, apollo3, mbed_nano, mbed_portenta architecture(s) and may be incompatible with your current board which runs on avr architecture(s).

Apart from potentially trying to import an incompatible library, am I doing something wrong? If not, are there any Arduino libraries for AVR architectures that will allow me to transfer data through Bluetooth via dealing with Services, Characteristics, Descriptors, etc...?

The Beetle Bluno BLE board is based on:

 - ICSP1: Atmega 328P
 - ICSP2: CC2540

More info about the board: https://wiki.dfrobot.com/Bluno_Beetle_SKU_DFR0339

body: The Device Is Not An Arduino Device (Uno,Mega,Nano,Mkr,etc)and arduinoBLE was made only arduino devices with builtin bluetooth


message:
ATMega4809 via Nano Every marked as 20Mhz, but does this confirm it is actually at 16Mhz?

If you go to the [official Arduino Nano Every page][1] and click the _Tech Specs_ tab, you'll see that it lists it as running at 20Mhz.

[![arduino nano every 20mhz][2]][2]

**Turn On Verbose Compile**

However, if you go into the Arduino IDE and go to File...Preferences... and turn on the _Show Verbose Output during: compilation_ then you can examine how the board is actually set when a program is uploaded.

[![show verbose output][3]][3]

**Examining the Output**

When you look at that output you will see that it seems to be setting the board to run at 16Mhz.

[![snapshot of compilation output][4]][4]

**Am I Looking At This Properly?**

It looks to me as if the board is actually set to run at 16Mhz, right?
Am I looking at that properly?

**Extra Question**

I'm attempting to confirm this because I am :

 1. writing code in Arduino IDE
 2. Compiling in Arduino IDE (to generate HEX file).
 3. Uploading to a stand-alone 40-pin ATMega4809

The ATMega4809 datasheet states the following:

[![16/20mhz datasheet][5]][5]

If I upload that sketch to the ATMega4809 40-pin chip, that means it will expect to run at 16Mhz, right?

**Set Fuses?**

Will the 40-pin chip be set to 16Mhz by the HEX file or will I need to set fuses on the chip to insure the chip is running at 16Mhz?

**FYI - Compiled For Correct Board**

Also you may wonder if I had the wrong board selected when I compiled, but here you can see I chose the Nano Every.

[![board set to nano every][6]][6]

  [1]: https://store.arduino.cc/usa/nano-every
  [2]: https://i.stack.imgur.com/VIr16.png
  [3]: https://i.stack.imgur.com/vRfpx.png
  [4]: https://i.stack.imgur.com/zkktV.png
  [5]: https://i.stack.imgur.com/TOBJP.png
  [6]: https://i.stack.imgur.com/oLL0g.png

body:
With the Nano Every they went out of their way to make it look like as much like original Nano, to the point of providing that "register emulation" feature to make it appear that it has the 328P's older style of GPIO registers.  Running at 16MHz just make sense if you want to behave like the common Nano as much as possible.

If you want to convince yourself that it's running at 16 MHz, you can blink an LED with causes of `__builtin_avr_delay_cycles(16000000);` in between.  This [busy-waits for the requested number of cycles][1].  If it's running at 20 MHz instead of 16, you would see something faster than a 1 second delay.

<s>[They keep][2] the configuration fuse values in a file fuses_4809.bin.</s>  On further investigation, it's not entirely clear what that file is for, despite containing the correct values.  The actual OSCCFG value being used (which is the same in the file) is defined [there directly][3] in the boards.txt:
```none
nona4809.bootloader.OSCCFG=0x01
```

[![OSCCFG documentation from datasheet.][4]][4]

So you can see it's set for 16 MHz on the Nano Every.  The `-DF_CPU` in the command line [originates from a line in boards.txt][5] for the Nano Every:
```properties
nona4809.build.f_cpu=16000000L
```

and works its way into the compile command-lines via [a line in platfrom.txt][6]:
```none
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} "-I{build.core.path}/api/deprecated" {includes} "{source_file}" -o "{object_file}"
```

The `D_CPU` macro exists to inform the compiled code what frequency it will be running at.  The OSCCFG is controlling the actual frequency, it's important that they agree for any timing related code.

When you upload it's the `"-Ufuse2:w:{bootloader.OSCCFG}:m"` that becomes `"-Ufuse2:w:0x01:m"` in the avrdude command line generated from the [upload recipe][7] in platform.txt that has the actual effect of configuring the chip for 16 MHz.

If you really wanted to run at 20 MHz, you could try tweak the definitions of these, but it probably makes more sense to look at something like [MCUdude MegaCoreX][8] which appears to have a board definition for the [ATMega4809 at 20 MHz][9].

  [1]: https://gcc.gnu.org/onlinedocs/gcc/AVR-Built-in-Functions.html
  [2]: https://github.com/arduino/ArduinoCore-megaavr/blob/1.8.7/boards.txt#L69
  [3]: https://github.com/arduino/ArduinoCore-megaavr/blob/1.8.7/boards.txt#L68
  [4]: https://i.stack.imgur.com/E0lK1.png
  [5]: https://github.com/arduino/ArduinoCore-megaavr/blob/1.8.7/boards.txt#L56
  [6]: https://github.com/arduino/ArduinoCore-megaavr/blob/1.8.7/platform.txt#L58
  [7]: https://github.com/arduino/ArduinoCore-megaavr/blob/1.8.7/platform.txt#L107
  [8]: https://github.com/MCUdude/MegaCoreX
  [9]: https://github.com/MCUdude/MegaCoreX/blob/v1.0.8/megaavr/boards.txt#L84


message:
How to sue Arduino Nano to control Stepper motor with Firmata

I have a stepper motor and at present it is controlled by a sketch all working fine. I need now to add it to a Win32 app to control it in circuit with existing Servo Motor. The servo Motor is working well via Firmata from Win32 app as follows

in setup part

    arduino.pinMode(9, Arduino.SERVO);

In loop

     private void btn_set_servo_Click(object sender, EventArgs e)
            {
                int angle = Convert.ToInt32(Math.Round(numupdwn_degrees.Value, 0));
                arduino.servoWrite(9, angle);//tell the servo motor go to the position
            }

How do you drive the stepper motor using Firmata has anyone got an example I can see please?

body:
**Update:** I have created a C# .Net App to connect and control the stepper Motor. The code and a Readme file is available at

https://github.com/zizwiz/Arduino_Projects/tree/main/FirmataStepperMotorTest

-------------------------------------
**Initial Answer:**

After a bit of thinking time I have managed to start the stepper motor running with Firmata protocol from my C# Win32 app. This post is just a basic outline I use to get it running I need lots more thinking and tinkering till I get what I need but in case this is helpful here it is.

Create a button to press to start.
Create a thread when the button is clicked

       private void btn_stepper_start_Click(object sender, EventArgs e)
            {
               var thread = new Thread(() =>
               {
                   while (true)
                   {
                       RunStepper();
                   }

               });

                thread.IsBackground = true;
                thread.Start();

            }

In the function RunStepper() create the following

     private void RunStepper()
            {
                while (true)
                {
                    arduino.digitalWrite(7, Convert.ToByte(255));
                    arduino.digitalWrite(8, 0);
                    arduino.digitalWrite(9, 0);
                    arduino.digitalWrite(10, 0);
                    Task.Delay(10);
                    arduino.digitalWrite(7, 0);
                    arduino.digitalWrite(8, Convert.ToByte(255));
                    arduino.digitalWrite(9, 0);
                    arduino.digitalWrite(10, 0);
                    Task.Delay(10);
                    arduino.digitalWrite(7, 0);
                    arduino.digitalWrite(8, 0);
                    arduino.digitalWrite(9, Convert.ToByte(255));
                    arduino.digitalWrite(10, 0);
                    Task.Delay(10);
                    arduino.digitalWrite(7, 0);
                    arduino.digitalWrite(8, 0);
                    arduino.digitalWrite(9, 0);
                    arduino.digitalWrite(10, Convert.ToByte(255));
                    Task.Delay(10);
                }
            }

As mentioned this small basic example is just a start to prove I may be able to do what I need.


message:
Arduino Nano skips statements after Interrupt

I am using an Arduino to control an AC Phase Control Circuit to control some lamps.
The problem is that the interrupts seem to break the code inside the `loop()`.
This Code should just blink one lamp. But it doesnt!
What I found out so far:
The Led always has `dim_level[22]` so it seems like (at least the first) delay in the `loop` is skipped.
The strange thing:
When i add a statement that takes some time between the delays everything is working
For example

    void loop() {
      CH[0] = dim_level[0];
      Serial.println("---------------------------------------------------------");
      delay(500);
      CH[0] = dim_level[22];
      Serial.println("---------------------------------------------------------");
      delay(500);
    }

The not working code:

    #include <TimerOne.h>

    unsigned char channel_1 = 7;    // Output to Opto Triac pin, channel 1
    unsigned char channel_2 = 6;    // Output to Opto Triac pin, channel 2
    unsigned char channel_3 = 5;    // Output to Opto Triac pin, channel 3
    unsigned char channel_4 = 4;    // Output to Opto Triac pin, channel 4
    unsigned char CH1, CH2, CH3, CH4;
    unsigned char i = 0;
    unsigned char delay_time = 1;   // delay ms or flashing SPEED
    unsigned char clock_tick;        // variable for Timer1
    unsigned char CHANNEL_SELECT;    // variable for channel select

    unsigned char CH[] = {CH1, CH2, CH3, CH4};

    unsigned char dim_level[] = {5, 8, 10, 12, 15, 18, 20, 25, 30, 35, 45, 50, 55, 60, 65, 70, 75, 80, 82, 85, 88, 92, 95}; // don't use this massive for 60Hz
    // create new massive for 60Hz
    void setup() {
      Serial.begin(2000000);
      pinMode(channel_1, OUTPUT);// Set AC Load pin as output
      pinMode(channel_2, OUTPUT);// Set AC Load pin as output
      pinMode(channel_3, OUTPUT);// Set AC Load pin as output
      pinMode(channel_4, OUTPUT);// Set AC Load pin as output
      attachInterrupt(1, zero_crosss_int, RISING);
      Timer1.initialize(100); // set a timer of length 100 microseconds for 50Hz or 83 microseconds for 60Hz;
      Timer1.attachInterrupt( timerIsr ); // attach the service routine here

    }

    void timerIsr()
    {
      clock_tick++;
      if (CH[0] == clock_tick)
      {

        digitalWrite(channel_1, HIGH);   // triac firing
        delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
        digitalWrite(channel_1, LOW);    // triac Off
      }

      if (CH[1] == clock_tick)
      {
        digitalWrite(channel_2, HIGH);   // triac firing
        delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
        digitalWrite(channel_2, LOW);    // triac Off
      }

      if (CH[2] == clock_tick)
      {
        digitalWrite(channel_3, HIGH);   // triac firing
        delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
        digitalWrite(channel_3, LOW);    // triac Off
      }

      if (CH[3] == clock_tick)
      {
        digitalWrite(channel_4, HIGH);   // triac firing
        delayMicroseconds(10);           // triac On propogation delay (for 60Hz use 8.33)
        digitalWrite(channel_4, LOW);    // triac Off
      }
    }

    void zero_crosss_int()  // function to be fired at the zero crossing to dim the light
    {
      clock_tick = 0;
    }

    void loop() {
      CH[0] = dim_level[0];

      delay(500);
      CH[0] = dim_level[22];

      delay(500);
    }

Im new to arduino maybeIi miss some concepts but I read that interupts should not break delays outside interrupt

body:
Like [timemage][1] mentioned i had to qualify `ch` as `volatile`.
so:

    volatile unsigned char CH[] = {CH1, CH2, CH3, CH4};

is the fix

  [1]: https://arduino.stackexchange.com/users/70020/timemage


message:
Arduino parsing of a string using sscanf

Hello I am new to Arduino and C programming.
I wanted to parse string using sscanf fuction

This is my Program

    String hith;
    int field1,field2;
    float field3;
    int F1=0,F2=0;
    float F3=0;
    int h1,h3;
    float h2;

    void setup() {

      Serial.begin(9600);

    }

    void loop() {
      field1=5;
      field2=6;
      field3=56.67;
      F1=field1;
      F2=field2;
      F3=field3;

      hith =hith+F1+","+F3+","+F2;
      Serial.println(hith);

    sscanf(hith.c_str(),"%d,%f,%d",&h1,&h2,&h3);

    Serial.println(h1);
    Serial.println(h2);
    Serial.println(h3);
      hith="";

      delay(1000);
    }

I am only able to Parse Integer values but not Floating points.

body:
On 8-bit Arduinos support for %f from `printf` and `scanf` (and related functions) has been removed to save space.

Instead you should look at parsing the string into chunks with `strtok()` and use `atof()` to convert relevant chunks to floating point.


message:
How to reduce AnalogRead noise?

Currently trying to read off values from a photodiode through analogread. It's constantly so noisy and I thought it might be something wrong with my low-pass filter, but I decided to just connect a 1.5V battery to an analog pin and had just as much noise (upwards of 10mV oscillations). Is there a way around all of this noise? Because this makes the collected data unusable for my project.

[![this is how I connected the battery to read of analog values that were still noisy][1]][1]

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

Code to read off analog values:

```
int diodePin = A0;
int sensorValue = 0;
int sensorVoltage = 0;

void setup() {

  Serial.begin(57600);

}

void loop() {

sensorValue = analogRead(diodePin);
sensorVoltage = sensorValue*(5000/1024);
Serial.println(sensorVoltage);
delay(10);

}
```

body:
I always do two things for when "reading" analog data with an Arduino.

1. Measuring the voltage supply of the arduino board through its internal reference and calibrating with another 'good" voltmeter ("4 1/2" digits-20000 points or "3 3/4" digits-6000 points). ( Usefull link  https://www.instructables.com/Secret-Arduino-Voltmeter/ )

2. Sampling more analog datas to calculate a "mean" ... This can remove some "noise" and add "some bits". 16 samples would add "4" bits at your "readings". Of course, the global sample rate will be lower.

**Don't forget, ground star of wires !!!**


message:
Custom library for Arduino to encode and decode JSON Web Tokens

So I have been recently been trying to create a library for Arduino to encode and decode JSON Web tokens(JWT) using HMAC-SHA256.

For those unfamiliar, JWT has 3 parts - The header, body and signature. The header and body are in JSON format.

The header contains the hashing algorithm and token type while The body contains the data to be transmitted.

The header and body are converted to base64 format and arranged as "[header].[body]". The signature is created by running the hashing algorithm (HMAC-SHA256 in my case) on the "[header].[body]" and converting the result to base64 format.

Finally, the token is arranged as "[header].[body].[signature]"

More information can be found on - [https://jwt.io/introduction][1]

So far, I successfully managed to create the encoding part. I wanted to test the code for consistency, so I tried to run the code on an Arduino UNO and kept on calling the encoding function in void loop. Initially, the results were as expected -

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

The long line of text is the expected output. But suddenly, it does this -

[![enter image description here][3]][3]

Then there is a period where the output is blank and finally, this comes-

[![enter image description here][4]][4]

For some reason, only the signature part gets printed. Also, I have no idea what the last 2 outputs are. Finally, it goes blank for a second and then repeats the entire process

Can anyone please help me in figuring out what is going on and how do I solve it?

This is my code in the library-
custom_jwt.h

    #ifndef _CUSTOM_JWT_H_
    #define _CUSTOM_JWT_H_

    #include <Arduino.h>

    class CustomJWT{
    private:
        char* secretKey;

    public:
        char* header;
        char* payload;
        char* signature;
        String out;

        CustomJWT(char* secret);

        char* getSecret();

        void changeSecret(char* secret);

        void encodeJWT(char* string);

        void decodeJWT(char* string);

    };

    #endif //_CUSTOM_JWT_H_

custom_jwt.cpp

    #include "custom_jwt.h"
    #include "sha256.h"
    #include <Arduino.h>

    const char b64[]  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    const char head[] = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9";

    void decodeblock(unsigned char in[], char *clrstr) {
        unsigned char out[4];
        out[0] = in[0] << 2 | in[1] >> 4;
        out[1] = in[1] << 4 | in[2] >> 2;
        out[2] = in[2] << 6 | in[3] >> 0;
        out[3] = '\0';
        strncat(clrstr, reinterpret_cast<const char *>(out), sizeof(out));
    }

    void b64_decode(char *b64src, char *clrdst)
    {
        int c, phase, i;
        unsigned char in[4];
        char *p;

        clrdst[0] = '\0';
        phase = 0; i=0;
        while(b64src[i]) {
            c = (int) b64src[i];
            if(c == '=') {
                decodeblock(in, clrdst);
                break;
            }
            p = strchr(b64, c);
            if(p) {
                in[phase] = p - b64;
                phase = (phase + 1) % 4;
                if(phase == 0) {
                    decodeblock(in, clrdst);
                    in[0]=in[1]=in[2]=in[3]=0;
                }
            }
            i++;
        }
    }

    void encodeblock( unsigned char in[], char b64str[], int len ) {
        unsigned char out[5];
        out[0] = b64[ in[0] >> 2 ];
        out[1] = b64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
        out[2] = (unsigned char) (len > 1 ? b64[ ((in[1] & 0x0f) << 2) |
                                                 ((in[2] & 0xc0) >> 6) ] : '=');
        out[3] = (unsigned char) (len > 2 ? b64[ in[2] & 0x3f ] : '=');
        out[4] = '\0';
        strncat(b64str, reinterpret_cast<const char *>(out), sizeof(out));
    }

    void b64_encode(char *clrstr, char *b64dst) {
        unsigned char in[3];
        int i, len = 0;
        int j = 0;

        b64dst[0] = '\0';
        while(clrstr[j]) {
            len = 0;
            for(i=0; i<3; i++) {
                in[i] = (unsigned char) clrstr[j];
                if(clrstr[j]) {
                    len++; j++;
                }
                else in[i] = 0;
            }
            if( len ) {
                encodeblock( in, b64dst, len );
            }
        }
    }

    void b64_encode(unsigned char *clrstr, char *b64dst)
    {
        unsigned char in[3];
        int i, len = 0;
        int j = 0;

        b64dst[0] = '\0';
        while(j < 32) {
            len = 0;
            for(i=0; i<3; i++) {
                in[i] = clrstr[j];

                if(clrstr[j] && j < 32) {
                    len++; j++;
                }
                else in[i] = 0;
            }
            if( len ) {
                encodeblock( in, b64dst, len );
            }
        }
    }

    CustomJWT::CustomJWT(char *secret)
    {
        CustomJWT::secretKey = secret;
    }

    char * CustomJWT::getSecret()
    {
        return CustomJWT::secretKey;
    }

    void CustomJWT::changeSecret(char *secret)
    {
        CustomJWT::secretKey = secret;
    }

    void CustomJWT::encodeJWT(char *string)
    {
        //Create header and body
        int len = (strlen(string) + 2)/3*4;
        char str[len];
        b64_encode(string, str);
        while(str[strlen(str) - 1] == '=')
            str[strlen(str) - 1] = '\0';
        String temp = head;
        temp = temp + ".";
        temp = temp + str;
        //Convert passkey to unsigned int
        char* msg1 = CustomJWT::secretKey;
        size_t length = strlen(msg1 + 1);
        char* beg = msg1;
        char* end = msg1 + length + 1;
        uint8_t* key = new uint8_t[length + 1];
        size_t i = 0;
        for (; beg != end; ++beg, ++i)
        {
            key[i] = (uint8_t)(*beg);
        }
        //Initialise HMAC
        Sha256.initHmac(key, length + 1);
        //Convert string to char array
        char temp1[temp.length() + 10];
        temp.toCharArray(temp1, temp.length() + 10);
        //Obtain result
        Sha256.print(temp1);
        uint8_t* hash = Sha256.resultHmac();
        //Encode to b64
        len = ((32 + 2)/3)*4;
        char str1[len];
        b64_encode(hash, str1);
        while(str1[strlen(str1) - 1] == '=')
            str1[strlen(str1) - 1] = '\0';
        temp = temp + ".";
        temp = temp + str1;
        CustomJWT::out = temp;
    }

This is the code on the Arduino:

    #include <custom_jwt.h>

    int i;
    char key[] = "tester";
    char string[] = "{\"temp\":22.5,\"speed\":25.1}";
    CustomJWT jwt(key);

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

    void loop()
    {
      jwt.encodeJWT(string);
      Serial.println(jwt.out);
    }

I have used the SHA256 library that I found in this link with some minor modifications as mentioned here [https://arduino.stackexchange.com/questions/65038/hmac-sha256-in-arduino-use-case][5] so that it can compile:
[https://github.com/Cathedrow/Cryptosuite][6]

Any help will be appreciated.

  [1]: https://jwt.io/introduction
  [2]: https://i.stack.imgur.com/6nBPI.png
  [3]: https://i.stack.imgur.com/WfdoG.png
  [4]: https://i.stack.imgur.com/FQ14h.png
  [5]: https://arduino.stackexchange.com/questions/65038/hmac-sha256-in-arduino-use-case
  [6]: https://github.com/Cathedrow/Cryptosuite

body:
As [@Majenko][1] had pointed out in the comments, it was temp variable causing the problem. Or rather, strings in general seem to have a bad effect on the memory of the Arduino UNO. After I rewrote the code without using any strings at all, the problem was fixed and the program gave a consistent output.

  [1]: https://arduino.stackexchange.com/users/4143/majenko


message:
Serial monitor can't display float and double values with absolute greater than 4294967040=2^32-2^8

I have the following sketch:

```c++
void setup() {}

void loop() {
  float af = 4294967040.0;
  float bf = 4294967240.0;
  double ad = 4294967040.0;
  double bd = 4294967040.00001;
  Serial.println(af);
  Serial.println(bf);
  Serial.println(ad);
  Serial.println(bd);
}
```

The values of `af`, `bf`, `ad` and `bd` are way smaller than 3.402823466e38 which is the maximum for float values. The values can still be correctly operated with, but the result on the serial monitor however is `ovf` for `bf` and `bd`.

Why is that?

body:
It's not the data type, it's the printing routine that sets that limit.  In `Print.cpp`:

```c++
227   if (isnan(number)) return print("nan");
228   if (isinf(number)) return print("inf");
229   if (number > 4294967040.0) return print ("ovf");  // constant determined empirically
230   if (number <-4294967040.0) return print ("ovf");  // constant determined empirically
```

Don't ask why...


message:
Audrino mkr1500 keeps going offline

I am using a MKR1500 with an Arduino SIM. I am able to upload the code on the device using the web editor. But when once I am done uploading the code, the device shows status offline and I am unable to check if the data is changing in the dashboard. I am running the below code to test. Also if i check when was the last time it was active, it generally shows before flashing. Also found that when I detach the device from the web UI and select it again, it shows up the last active timing as when it was detached. But during that time I saw it was inactive. Is there something that i am missing?
Can someone please help me with it.
Thanks!
````#include "thingProperties.h"
int readSensor;
void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500);
  Serial.println("Hello world");
  // Defined in thingProperties.h
  initProperties();
  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}
void loop() {
  ArduinoCloud.update();
  // Your code here
  int sensor1 = analogRead(A1);
  int carbonMonoxide = analogRead(A2);
  int methaneSensor = analogRead(A3);
  Serial.println(sensor1);
  Serial.println(carbonMonoxide);
  Serial.println(methaneSensor);
  delay(1000);
 }
void onADCvalueChange() {
  // Do something
}
````

body:
The mkr1500 is not compatible with the sim right only the mkr1400 is working with the sim SORRY!
Check The Page [store.arduino.cc/digital/sim][1]

  [1]: https://store.arduino.cc/digital/sim


message:
How to properly send bytes between RPI and Arduino over I2C while using ISR without IOerrors?

I have a I2C connection between an RPI 3B+ and Arduino Nano. I want to send a key and a corresponding value byte, and the arduino does something with that inside a timed ISR. Which works. But I get IOerrors at the RPI side, probably because the ISR is busy. So I did a little test. Every 10000 messages send:

 - 245 IOerrors at 51,281 Hz ISR
 - 104 IOerrors at 25,600 Hz ISR
 - 28 IOerrors at 6,400 Hz ISR

Is there any way to have less or no IOerrors? I need about 25,600 kHz for my ISR.

RPI side:

    bus.write_i2c_block_data(0x60, 0x00, [key, val])

Arduino side message handler called as Wire.onReceive(msg_handler);:

    void msg_handler(int bitstream) {
         Wire.read();
         int pin = Wire.read();
         int val = Wire.read();
         Serial.println(pin);
         Wire.begin(0x60);

I do the wire begin every time because otherwise once it had a IOerror it stops printing on the serial.
My wiring is 18 AWG and about 20cm. The error:

    [Errno 121] Remote I/O error

body:
What i2c clock speed are you using?

Even at the faster "fairly standard" speed of 400kHz, that's 2.5us per bit. For a two byte transfer, that's 4us for the data alone, which is 25000 transfers per second. Add on the start and stop bits, plus processing time and you can see that your target data rate isn't possible.

i2c just isn't that fast as standard, though there are much faster "non standard" modes.


message:
Unwanted Wi-Fi Jamming by ESP8266

I bought an ESP8266-01 module. I attempted to upload following code onto it.

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

    void loop() {
      // put your main code here, to run repeatedly:
    Serial.println("I'm working");
    Serial.println(millis());
    }
Then I powered it and there was nothing in Serial monitor. Also my computer lost wifi connection. What's the cause of this error? How to solve it?

body:
**Solved**:
I catched more details. ESP creates Wi-Fi network. It causes jamming.


message:
Error compiling ESP32 Wrover Module in Linux Virtual Machine

SO i have been getting this error window when i compile a simple code to run different LED lights on the ESP32-S2-SOLA (Wrovere) module

Code:
```cpp
int LED_BUILTIN = 2;

void setup() {
    pinMode (LED_BUILTIN, OUTPUT);
}

void loop() {
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000);
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000);
}

```

error:
```
Arduino: 1.8.15 (Linux), Board: "ESP32 Wrover Module, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), QIO, 80MHz, 115200, None"

Traceback (most recent call last):
  File "/home/student/.arduino15/packages/esp32/tools/esptool_py/3.0.0/esptool.py", line 38, in <module>
    import serial
ImportError: No module named serial
exit status 1
Error compiling for board ESP32 Wrover Module.
```

body:
As Juraj and Majenko pointed out in the comments, your python installation lacks the module `serial`.
In Linux the best way to install it would be `pip` or rather `pip3` for Python 3:
```
sudo pip3 install serial
```
If you don't have `pip3` on you system, install `python3-pip` first, e. g. using `apt`:
```
sudo apt install python3-pip
```


body:
The error can be solved by installing Python serial package via these two commands

$ sudo apt-get update -y
$ sudo apt-get install -y python-serial


message:
Input vs input_pullup

I'm a beginner in Arduino and can't understand some things. How does input pin in Arduino work? I want to set one of the pins as input. When should I use input and when input_pullup? What are the differences between them?

body:
**Input pin working**-

An input pin on an arduino board uses something called   [Tristate buffer][1] to expect a voltage at the pin.

**Input pullup**-

When a pin is configured just as an input (without a definite voltage connected to it), the pin will return random values based on the electrical interference present around it, for example the neighbouring pin.

So to solve this issue, input pullups are used. Essentially it sets the default state of the pin to HIGH or 1, so that the pin is not affected by interference.

You can experience this yourself using the following program, with a pushbutton from Ground to pin 7, and the Serial monitor-

No pullup-
```
void setup(){
// Dont have to put any pin definitions here as by default it input
// This code will return random values until the button is pressed
Serial.begin(9600);
}

void loop(){
Serial.println(digitalRead(7));
}
```

Now for the one with Pullup-

```
void setup(){
pinMode(7, INPUT_PULLUP);
Serial.begin(9600);
// This code will return 1/HIGH until the button is pressed
}

void loop(){
Serial.println(digitalRead(7));
}
```

Random info- There's input pulldown on some boards, guess what that does?

  [1]: https://www.electronics-tutorials.ws/logic/logic_9.html


body:
The pin inputs are sensitive enough to nearby electrical noise that if the pin is floating - not positively pulled up to the supply voltage, or down to ground - the input will read randomly HIGH or LOW. A pullup resistor of 10K Ohms or so connected between the pin and the supply voltage is strong enough to overcome the noise, but is itself easily overcome by a signal applied to at the pin input:

<!-- 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/hP7yf.png)

<!-- End schematic -->

This means that when the pin is not connected, it will have stable HIGH reading.
While you can put the pullup on your circuit board, as in the schematic above, Arduinos have a built-in pullup resistor that can be connected to the pin simply by selecting 'INPUT_PULLUP' in your code, and it does exactly the same thing. It is a convenient way to save space and a component on your circuit board or make it slightly quicker to wire your breadboard. And in the case of a breadboard in particular, the plug-wires are excellent antennas for picking up noise, while the built-in pullup resistor is within the chip, close the pin-receiver, and it makes the circuit dramatically more stable.


message:
Seeking to write a ton of information to an SD card as close to live as possible

So I've recently started a project where I am using an accelerometer, along with a SD card breakout board. I've been able to get information to write properly to the SD card with no issues whatsoever. However, my speed is a bit lower than I would like, at about only 40Hz or so, where my accelerometer can log data at 260Hz (MPU-6050). Each reading contains an X, Y, Z, and timestamp value since recording started. Each reading is output into a .txt file for later separation via comma-separated-value sorting in Excel(I wish) or GNUplot, which handles the massive sample size much better.

I've referenced https://forum.arduino.cc/t/how-to-write-data-with-high-sampling-rates-to-a-sd-card/281496/9 to try and figure this out, but I couldn't get much out of it. I don't understand arrays very well beyond the fact they are just tables like in excel, and can be set up in 1, 2, 3, or more dimensions.

I've read around a bit and it seems my problem is that I'm closing and opening the file each and every write cycle. However, I don't know how to get out of doing this as the program seems to not run properly if I don't close out the file or if I use flush. My general idea of how this could flow without opening/close cycles every single time would be:

>1. Create arrays for each variable (X, Y, Z, elapsedTime)
>2. Take all my recordings for a given time, maybe five-hundred readings or so which would come out to about 12 seconds, or whatever possible value I can squeeze out of my Atmega328P and maintain program stability, and shove them into their respective arrays. Ideally the longer the better, but I understand I have memory constraints.
>3. In one write-cycle, I write all the values into CSV form, or even multiple print cycles cycling through each array cell continuously until all the values are input with the proper format.
>4. Clear the arrays of all the info they held, and return to step 2.

Really appreciate any help you guys can offer. Thank you!

```
//

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;
const int chipSelect = 10;
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens

                                                                           //SD CARD WRITE CODE BEGIN
 {
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_8_G);
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}

unsigned long startMillis;
unsigned long currentMillis;
unsigned long elapsedTime;
int rawMillis;
void loop() {
  digitalWrite(recordingLed, LOW);
  int buttonRecord = digitalRead(2);                                                //Check button for GND input
  /* Get new sensor events with the readings */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

// make a string for assembling the data to log:                                    //SD CARD VALUES ASSIGN BEGIN
  int X = "";
  int Y = "";
  int Z = "";
  String timeofRecord = String(millis()/1000.0, 10);
  X = (a.acceleration.x/9.81);
  Y = (a.acceleration.y/9.81);
  Z = (a.acceleration.z/9.81);
  if(buttonRecord == false){                                                        //Toggle record status upon pin 2 going to GND
    delay(500);
    recordStatus = !recordStatus;                                                   //If button is pressed, make recordStatus switch from true to false.
    startMillis = millis();
  }

if(recordStatus == true){                                                           //While record is toggled, do below
    rawMillis = millis()-startMillis;
    String elapsedTime = String(rawMillis/1000.00, 3);
    File dataFile = SD.open("datalog.txt", FILE_WRITE);
      if (dataFile) {                                                               // if the file is available, write to it:
    digitalWrite(recordingLed, HIGH);
    dataFile.print(elapsedTime);
    dataFile.print(", ");
    dataFile.print(X);
    dataFile.print(", ");
    dataFile.print(Y);
    dataFile.print(", ");
    dataFile.print(Z);
    dataFile.println("");
    dataFile.close();
  }
}
  // if the file isn't open, pop up an error:
  else {
    Serial.println("error opening datalog.txt");
    }
}
```

**UPDATE**

So I've been messing with this a while, and I believe I just about have it figured out. I have arrays set up for time, X, Y, and Z and they are populating values correctly. However, I can't seem to get into my SD card file. There is no issue when the setup initializes, it's like it skips the

>if (dataFile){

entirely. The modified code is below here. There's no shutdowns, and the program loops continuously so I don't *think* I'm running out of memory or having any power issues. The red LED on the SD card is flashing as though it's being written. Even if I remove the if(dataFile) check and force the commands contained in the if statement to execute, my txt file is still left empty. Previously I was writing to this just fine. Memory problem? I have less than 500 bytes of memory available. Possibly this is the cause? Or is it the for loop causing my trouble?

```
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;
const int chipSelect = 10;
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  while (!Serial)
    delay(10);
                                                                           //SD CARD WRITE CODE BEGIN
 {
  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_4_G);
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}

float startMillis;
float elapsedTime[3];
float rawMillis;

float X[3];
float Y[3];
float Z[3];

void loop() {
  digitalWrite(recordingLed, LOW);
  int buttonRecord = digitalRead(2);                                                //Check button for GND input
  /* Get new sensor events with the readings */
  if(buttonRecord == false){                                                        //Toggle record status upon pin 2 being pulled down to GND
    delay(500);
    recordStatus = !recordStatus;                                                   //If button is pressed, make recordStatus switch from true to false.
    startMillis = millis();
    Serial.print("BUTTON PRESSED");
  }
  if(recordStatus == true){                                                         //While record is toggled, do below
   digitalWrite(recordingLed, HIGH);
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);
for(int arrayNumber = 0; arrayNumber <= 3; ++arrayNumber){
    sensors_event_t a, g, temp;
    mpu.getEvent(&a, &g, &temp);

    X[arrayNumber] = (a.acceleration.x);                                             //SD CARD VALUES ASSIGN BEGIN/DO MATH TO CALCULATE G'S
    Y[arrayNumber] = (a.acceleration.y);
    Z[arrayNumber] = (a.acceleration.z);

    rawMillis = millis()-startMillis;
    elapsedTime[arrayNumber] = rawMillis;
    Serial.println(elapsedTime[arrayNumber]);
    Serial.println(X[arrayNumber]);
    Serial.println(Y[arrayNumber]);
    Serial.println(Z[arrayNumber]);
    Serial.println(arrayNumber);                                                     // diagnostic for checking to make sure arrays are being populated properly
}

    File dataFile = SD.open("datalog.txt", FILE_WRITE);
    Serial.print("LEFT LOGGING LOOP, ENTERING WRITE LOOP");

  if (dataFile) {                                                                    // if the file is available, write to it
    for(int arrayNumber = 0; arrayNumber <= 3; ++arrayNumber){
 Serial.print("NOW INSIDE WRITE LOOP");                                              // confirmation of being inside the write loop, and writing data to the file
    String(dataString) = (
    elapsedTime[arrayNumber] + String(", " ) + X[arrayNumber] + String(", ") + Y[arrayNumber] + String(", ") + Z[arrayNumber]         //Format data for output to the comma separated format for excel/gnuplot
  );
    dataFile.println(dataString);
       }
       dataFile.close();
       Serial.println("WRITE LOOP DONE");
    }
  }
}
```

body:
So I spent a while longer banging my head on the wall, and I finally found a solution to my issue. [@DaveNewton](https://arduino.stackexchange.com/users/8583/dave-newton) provided several links that lead to other links, and I found my way [to here](https://forum.arduino.cc/t/why-is-the-sd-library-slow/49791) where some not-so-common knowledge is explained. It appears that for some reason the FILE_WRITE function is slow, and takes a lot of time to execute.

This can be substituted by using
>O_CREAT | O_WRITE | O_APPEND

as this first checks if the file is created, and if not, creates it. Once the or check passes for the O_CREAT section, it moves on into the O_WRITE command. Then the O_APPEND checks if there is any data already present and if so, move to the end of the line to begin new data logging.

My finished code in it's entirety is below, I hope it helps someone in the future. I'm using a MicroCenter 32GB (class 10) Micro SD card to store the data, [this SD card breakout board](https://www.adafruit.com/product/254), and [this MPU-6050 based accelerometer](https://www.amazon.com/HiLetgo-MPU-6050-Accelerometer-Gyroscope-Converter/dp/B078SS8NQV).
```
// This program is designed to log data to an SD card via an arduino Uno, and SD card breakout board, and a MPU-6050 accelerometer module.

// MPU-6050:                https://www.amazon.com/HiLetgo-MPU-6050-Accelerometer-Gyroscope-Converter/dp/B078SS8NQV
// Micro SD Card Breakout:  https://www.adafruit.com/product/254
// Micro SD Card I used:    https://www.microcenter.com/product/485584/micro-center-32gb-microsdhc-card-class-10-flash-memory-card-with-adapter

// Link to original Arduino StackExchange submission where I worked through this code:  https://arduino.stackexchange.com/questions/84961/seeking-to-write-a-ton-of-information-to-an-sd-card-as-close-to-live-as-possible

#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

int recordStatus = false;                                                   //Default recordStatus is zero.
int recordingLed = 3;                                                       //Output to show us whether we are recording or not.
const int chipSelect = 10;                                                  //Use pin 10 as our CS pin
Adafruit_MPU6050 mpu;

void setup(void) {
  pinMode(2, INPUT_PULLUP);                                               //Set pin 2 to have a default HIGH state using the internal pull up resistor.
  pinMode(3, OUTPUT);
  Serial.begin(500000);
  SPI.begin();
  SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));       //I have no idea if this really does anything, but I figure I'd just leave it since it's not causing any problems.
  while (!Serial)
    delay(10); // will pause Zero, Leonardo, etc until serial console opens
                                                                           //SD CARD WRITE CODE BEGIN
 {

  Serial.print("Initializing SD card...");

  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    while (1);
  }
  Serial.println("card initialized.");
}
                                                                              //SD CARD WRITE CODE END

  Serial.println("Adafruit MPU6050 test!");                                   //MPU6050 ACCELEROMETER INITIALIZATION CODE BEGIN
  // Try to initialize!
  if (!mpu.begin()) {
    Serial.println("Failed to find MPU6050 chip");
    while (1) {
      delay(10);
    }
  }
  Serial.println("MPU6050 Found!");

  mpu.setAccelerometerRange(MPU6050_RANGE_16_G);                            //I originally had this at 4 but was capping results, so I moved it up to 16. Feel free to lower this if you know your application will not exceed 4Gs
  switch (mpu.getAccelerometerRange()) {
  case MPU6050_RANGE_2_G:
    break;
  case MPU6050_RANGE_4_G:
    break;
  case MPU6050_RANGE_8_G:
    break;
  case MPU6050_RANGE_16_G:
    break;
  }
  mpu.setGyroRange(MPU6050_RANGE_500_DEG);                                //I'm not using the gyro at all, but 500 degrees seems like a good value to use here.
  switch (mpu.getGyroRange()) {
  case MPU6050_RANGE_250_DEG:
    break;
  case MPU6050_RANGE_500_DEG:
    break;
  case MPU6050_RANGE_1000_DEG:
    break;
  case MPU6050_RANGE_2000_DEG:
    break;
  }

  mpu.setFilterBandwidth(MPU6050_BAND_260_HZ);                              //Select maximum frequency for recording.
  Serial.print("Filter bandwidth set to: ");
  switch (mpu.getFilterBandwidth()) {
  case MPU6050_BAND_260_HZ:
    Serial.println("260 Hz");
    break;
  case MPU6050_BAND_184_HZ:
    Serial.println("184 Hz");
    break;
  case MPU6050_BAND_94_HZ:
    Serial.println("94 Hz");
    break;
  case MPU6050_BAND_44_HZ:
    Serial.println("44 Hz");
    break;
  case MPU6050_BAND_21_HZ:
    Serial.println("21 Hz");
    break;
  case MPU6050_BAND_10_HZ:
    Serial.println("10 Hz");
    break;
  case MPU6050_BAND_5_HZ:
    Serial.println("5 Hz");
    break;

   SPI.endTransaction();
  }
                                                                                //MPU6050 ACCELEROMETER INITIALIZATION CODE END
}
float X;
float Y;
float Z;
float startMillis;
float currentMillis;
float rawMillis;
int tickMillis = LOW;

void loop() {
  int buttonRecord = digitalRead(2);                                                //Check button (pin 2) to see if it is grounded through momentary switch.
  // Get new sensor events with the readings.

if(buttonRecord == LOW){                                                           //If buttonRecord switches to GND, switch tickMillis to it's opposite value as a toggle and store startMillis, then wait 300ms as a debounce.
    tickMillis = !tickMillis;
    startMillis = millis();
    delay(300);
}
    if(tickMillis == HIGH){
    File dataFile = SD.open("datalog.txt", O_CREAT | O_WRITE | O_APPEND);           // Create datalog.txt. If already created, move to end of stored data, and begin write function
    if (dataFile) {                                                                 // if the file is available, write to it:

  for(uint8_t i = 0; i < 250; i++){                                                 // For i = 0, execute the below code. Then increment i by 1. Once past 250, exit for() loop
    digitalWrite(recordingLed, HIGH);

    sensors_event_t a, g, temp;                                                     // Commands to trigger event sensing and acceleration logging.
    mpu.getEvent(&a, &g, &temp);

    X = a.acceleration.x/9.81;                                                      // Divide normal acceleration return values to calculate G forces
    Y = a.acceleration.y/9.81;
    Z = a.acceleration.z/9.81;

    rawMillis = millis()-startMillis;                                               // Take our current millis value and subtract our beginning startMillis from it to get how long we've actually been recording.

    dataFile.print(rawMillis/1000, 3);                                              // Store data in a Comma-Seperated-Value format. The '3' after rawMillis/1000 says print out to 3 decimal places.
    dataFile.print(", ");                                                           // I just use a txt file since GNUplot can plot from that value, but a CSV library could probably be used here.
    dataFile.print(X);                                                              // Excel doesn't allow plots beyond 255 datapoints for god knows why. So GNUplot is basically a necessity to plot these accurately to timestamp.
    dataFile.print(", ");
    dataFile.print(Y);
    dataFile.print(", ");
    dataFile.print(Z);
    dataFile.println();
    }
    dataFile.flush();
    dataFile.close();
    }
   else {
    delay(500);
    Serial.println("error opening datalog.txt");
    }
  } else {
        digitalWrite(recordingLed, LOW);
    }
}
```

Thanks so much for the comments/advice everyone. It's really appreciated. The final recording frequency for this is ~170Hz, which is good enough for me.


message:
Trying to use I2C accelerometer and SPI OLED

I'm trying to stream the data coming from my I2C MMA8452Q accelerometer to an Adafruit-based SSD1351 OLED RGB display that uses SPI via an Arduino UNO.

When I run example code for the accelerometer I can see it outputting data to the serial monitor, and when I run my code for the screen using a joystick as test input it graphs the values nicely.

When I try and build in the I2C example code into my code for the display, the moment I include to the code to read the values from the accelerometer, the program runs setup and then goes blank after that. When I block out the sensor read and swap in the joystick reads it works fine again.

I've been staring at all kinds of forum posts about using SPI and I2C simultaneously but I haven't really found any with a straightforward solution or they use a very different board.

```#include <Adafruit_GFX.h>
#include <Adafruit_SSD1351.h>
#include <SparkFun_MMA8452Q.h>
#include <SPI.h>
#include <Wire.h>

#define SCREEN_WIDTH  128
#define SCREEN_HEIGHT 128 // Change this to 96 for 1.27" OLED.

// You can use any (4 or) 5 pins
#define SCLK_PIN 2  // not using this as I've got it setup
#define MOSI_PIN 3  // on the hardware SPI pins as per the text below
#define DC_PIN   4
#define CS_PIN   5
#define RST_PIN  6  // not in use

#define joy_XPin A1
#define joy_YPin A0

// Color definitions
#define BLACK           0x0000
#define BLUE            0x001F
#define RED             0xF800
#define GREEN           0x07E0
#define CYAN            0x07FF
#define MAGENTA         0xF81F
#define YELLOW          0xFFE0
#define WHITE           0xFFFF

// Option 1: use any pins but a little slower
// Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, CS_PIN, DC_PIN, MOSI_PIN, SCLK_PIN, RST_PIN);

// Option 2: must use the hardware SPI pins
// (for UNO thats sclk = 13 and sid(which is SDA on my display) = 11) and pin 10 must be
// an output. This is much faster - also required if you want
// to use the microSD card (see the image drawing example)
Adafruit_SSD1351 tft = Adafruit_SSD1351(SCREEN_WIDTH, SCREEN_HEIGHT, &SPI, CS_PIN, DC_PIN, RST_PIN);

MMA8452Q accel; // intialise sensor - SDA/SCL connected to A4/A5 pins as per example code

#define graphLength 32

int joy_X, joy_Y;
int tilt_X, tilt_Y;

int graphY[graphLength] = {0};
int graphX[graphLength] = {0};

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

  tft.fillScreen(BLACK);

  tft.setCursor(10,64);
  tft.setTextColor(WHITE);
  tft.println("Welcome, have fun");

  delay(2000);
  tft.fillScreen(BLACK);
}

void loop() {

  // scaled inputs to be smaller and offset to be in the middle of the screen
  joy_X = (analogRead(joy_XPin) / 32)+48;
  joy_Y = (analogRead(joy_YPin) / 32)+48;

  // when this block is included everything breaks
  // this is the code to read the accelerometer input so I'm pretty sure the issue is here.
  /*
  if(accel.available()){
    tilt_X = accel.getCalculatedX() * 10;
    tilt_Y = accel.getCalculatedY()* 10;
  }
  */

  graphY[graphLength - 1] = tilt_X; // swap tilt_X/Y with joy_X/Y to graph joystick inputs
  graphX[graphLength - 1] = tilt_Y;
  for(int i = 0; i <= (graphLength - 1); i++){  // invokes undefined behaviour but it works for now
    tft.drawPixel(i,graphY[i],RED);
    tft.drawPixel(i,graphX[i],BLUE);
  }

  delay(5);
  graphShiftAlong();
}

// Just functions to clear the things I've drawn on the display rather than trying to wipe the whole display each time.

void clearPixel(uint16_t x, uint16_t y){
  tft.drawPixel(x, y, BLACK);
}

void drawRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color){
  int x1,y1,x2,y2;
  w = w/2;
  h = h/2;

  x1 = x - w;
  y1 = y - h;
  x2 = x + w;
  y2 = y + h;

  tft.drawLine(x1,y1,x1,y2,color); // top left to bottom left
  tft.drawLine(x1,y1,x2,y1,color); // top left to top right
  tft.drawLine(x2,y1,x2,y2,color); // top right to bottom right
  tft.drawLine(x2,y2,x1,y2,color); // bottom right to bottom left
}

void clearRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h){
  drawRect(x,y,w,h,BLACK);
}

// Sets the 'old' data to be drawn as black and redraws it one pixel offset
// Compiler gives me red text but not errors so I'm running with it for now
void graphShiftAlong(){
  for(int i = 0; i <= (graphLength - 1); i++){
    tft.drawPixel(i,graphY[i],BLACK);
    tft.drawPixel(i,graphX[i],BLACK);
    graphX[i] = graphX[i+1];
    graphY[i] = graphY[i+1];
  }
}
```

The example code I'm using for the sensor is here:
```/*
  Library for the MMA8452Q
  By: Jim Lindblom and Andrea DeVore
  SparkFun Electronics

  Do you like this library? Help support SparkFun. Buy a board!
  https://www.sparkfun.com/products/14587

  This sketch uses the SparkFun_MMA8452Q library to initialize
  the accelerometer and stream calcuated x, y, z, acceleration
  values from it (in g units).

  Hardware hookup:
  Arduino --------------- MMA8452Q Breakout
    3.3V  ---------------     3.3V
    GND   ---------------     GND
  SDA (A4) --\/330 Ohm\/--    SDA
  SCL (A5) --\/330 Ohm\/--    SCL

  The MMA8452Q is a 3.3V max sensor, so you'll need to do some
  level-shifting between the Arduino and the breakout. Series
  resistors on the SDA and SCL lines should do the trick.

  License: This code is public domain, but if you see me
  (or any other SparkFun employee) at the local, and you've
  found our code helpful, please buy us a round (Beerware
  license).

  Distributed as is; no warrenty given.
*/

#include <Wire.h>                 // Must include Wire library for I2C
#include "SparkFun_MMA8452Q.h"    // Click here to get the library: http://librarymanager/All#SparkFun_MMA8452Q

MMA8452Q accel;                   // create instance of the MMA8452 class

void setup() {
  Serial.begin(9600);
  Serial.println("MMA8452Q Basic Reading Code!");
  Wire.begin();

  if (accel.begin() == false) {
    Serial.println("Not Connected. Please check connections and read the hookup guide.");
    while (1);
  }
}

void loop() {
  if (accel.available()) {      // Wait for new data from accelerometer
    // Acceleration of x, y, and z directions in g units
    Serial.print(accel.getCalculatedX(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedY(), 3);
    Serial.print("\t");
    Serial.print(accel.getCalculatedZ(), 3);
    Serial.println();
  }
}

body:
Your SPI is not setup for the Arduino UNO. Check another example for SPI and you will be using pins 11 and 13, this is mandatory and 8,9,10 or any three and there is a definition statement for these 3 pins - look at the example for your display.
For I2C do you have pullup resistors on both I2C lines 4.7k up to 10k? These are required.
Good luck


message:
Problem with DC motor

I've got a circuit with Arduino UNO Rev3, DC motor, button to switch direction of rotation and potentiometer to regulate revs. The problem is that usually when I increase voltage using potentiometer, motor doesn't want to start rotating by itself and it does only when I move its shaft with finger or when I press the button again. I would undrestand that it can be due to friction and that's why moving shaft with finger helps, but why does motor start rotating when I press the button changing direction?

Here is my circuit:
[![enter image description here][1]][1]

And here is my code:
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/0mnws.png
  [2]: https://i.stack.imgur.com/2jnre.png

body:
Firstly, you need a motor driver to drive a motor from an Arduino. You cannot drive it directly from IO pins.

Secondly by using a potentiometer like that for controlling the speed you are massively starving the motor of power (not that the Arduino *can* provide such power, and if it could then the potentiometer would smoke).

Your design should be:

* Potentiometer into an analog input to control the speed using PWM
* Outputs from the Arduino to control the direction (GPIO x 2) and speed (PWM) to a motor driver (L293 is commonly available)
* Motor connected to the motor driver
* Power supply suitable for your motor connected to the motor driver

There are many many examples on the web that show you this kind of circuit. Follow one.


body:
First of all, disconnect your Motor which is directly connected to your UNO if you want your Board to be safe and sound.

Arduino or any other microcontroller ICs are not made for directly running High powered loads.

The work of a microcontroller is to produce signals which must be run through a transistor or an IC amplification method to drive high loads.

You are running the Motor directly from UNO pins. What wrong may it go?

   1. If your motor consumes current more than 20mA then the pin where you connected the arduino is to heat up and will burn if you continue further.
   2. Let's suppose your motor consumes current less than 20mA, still it has a high risk that a motor sometimes creates very high voltage and current surge in a specific condition.

If you continue to do so, you will end up burning those pin completely.

So what befits your project seems to be a motor driver IC like L293D or L298N

Instead of a motor,  connect Motor Driver IC logic level input to digital output pin 3 and 4 of Arduino then connect a motor to the output of the Motor Driver IC

More about these ICs can be found in Datasheets


message:
DS1337 with shared I2C pull-up

I have a project using an ATMEGA328P and a DS1337 RTC chip. The DS1337 is an 8 pin IC with VCC at pin 8 and GND at pin 4. According to the [datasheet][1] both pin 5 (SDA) and pin 6 (SCL) need an external pull-up. From what I read elsewhere, a pull-up of 4.7K to 10K for each I2C pin should be good enough. Considering the position of both I2C pins to each other and the VCC pin, I was thinking of simplifying things by using a shared 10K pull-up. This [post][2] suggests that it should be possible, but I am still not sure. Does anyone have experience with this, that is using a shared pull-up to an I2C connection? What could be some problems, if any, by doing this?

  [1]: https://datasheets.maximintegrated.com/en/ds/DS1337-DS1337C.pdf
  [2]: https://electronics.stackexchange.com/questions/37158/sharing-a-pull-up-resistor

body:
You need *at least* one pull-up on the SDA pin and *at least* one pull-up on the SCL pin. You cannot use the same pull-up for both pins as you will be shorting the two pins together.

The pull-ups are required on the I2C signals, not the pins of a chip. If you have multiple chips on the I2C bus you only need one pull-up on each signal. It really doesn't matter (given that I2C buses are intended to be short) where on the signal the pull-up is in relation to any one chip.

I would personally say that 4.7kΩ to 10kΩ is too high. I don't use more than 3.3kΩ pull-ups for I2C, and more likely 1kΩ if I am using higher speed (e.g., 1MHz) I2C.


message:
5v pin not outputting any voltage in Arduino Nano ble 33

I bought an Arduino Nano ble 33 but when I try to power my MQ-4 and MQ-8 sensors, these don't turn on at all, they do turn on if I switch to the 3.3V tho.

Is there anything special that I need to do to be able to use the 5V pin, or my board is faulty?

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

P.S: When I say 5V I mean the pin next to the green rectangle.

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

body: i think you solder the two pads but i'll tell you something: use the 3.3v pin


message:
How do I control a servo with python through an Arduino

I'm trying to make it so I can control 2 servos with data that I get from a python script that tracks my face.

I have found 2 libraries that do this:pySerial and pyfirmata.

Is one superior to the other one, are there more libraries, or should approach things differently.

body:
I'd say pyFirmata can work but controling servos ... NOPE!
use pyserial and add the code


message:
Question regarding using Arduino and MIDI

I'm using an Arduino Leonardo for sending MIDI In and Out messages to Ableton Live.

Components include a Potentiometer, a Capacitive Touch Sensor, and a DC Motor, which I'm powering with a L298N Motor Driver.

Right now I have it set up so that I can record automation in by moving the potentiometer, send a MIDI note in when I'm touching the fader, and follow automation using the DC Motor.

The problem that I'm having is that when I go to play my tracks, the automation that I recorded with the potentiometer is deactivated, and therefore my motor doesn't respond. I believe this is because I'm sending MIDI Input and Output at the same time. Here's the current version of the code:

```
#include <Control_Surface.h>
#include <CapacitiveSensor.h>

int minimumCp = 200;
int lastfaderPosition = 0;     // previous state of the button

const byte touchSend = 7;
const byte touchReceive = 8;

CapacitiveSensor touchSensor = CapacitiveSensor(touchReceive, touchSend);
USBMIDI_Interface midi;
CCPotentiometer faderPosition { A0, MIDI_CC::General_Purpose_Controller_1 };

int incomingChannel;
int incomingNote;
int incomingVelocity;
const byte mainFaderPin = 0;
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;
byte motorSpeed = 150;
byte tolerance  = 40;
double faderMax = 0;
double faderMin = 0;

struct MyMIDI_Callbacks : FineGrainedMIDI_Callbacks<MyMIDI_Callbacks> {

  void onControlChange(Channel channel, uint8_t controller, uint8_t value, Cable cable) {
    incomingNote = controller;
    incomingVelocity = value;
  }
  void onProgramChange(Channel channel, uint8_t program, Cable cable) {
    Serial << "Program Change: " << channel << ", program " << program << ", "
           << cable << endl;
  }
  void onAfterTouchChannel(Channel channel, uint8_t pressure, Cable cable) {
    Serial << "Channel Pressure: " << channel << ", pressure " << pressure
           << ", " << cable << endl;
  }
  void onPitchBend(Channel channel, uint16_t bend, Cable cable) {
    Serial << "Pitch Bend: " << channel << ", bend " << bend << ", " << cable
           << endl;
  }
  void onSystemExclusive(SysExMessage se) {
    Serial << F("System Exclusive: [") << se.length << "] "
           << AH::HexDump(se.data, se.length) << ", " << se.cable << endl;
  }
  void onTimeCodeQuarterFrame(uint8_t data, Cable cable) {
    Serial << "MTC Quarter Frame: " << data << ", " << cable << endl;
  }
  void onSongPosition(uint16_t beats, Cable cable) {
    Serial << "Song Position Pointer: " << beats << ", " << cable << endl;
  }
  void onSongSelect(uint8_t songnumber, Cable cable) {
    Serial << "Song Select: " << songnumber << ", " << cable << endl;
  }
  void onTuneRequest(Cable cable) {
    Serial << "Tune Request: " << cable << endl;
  }
  void onClock(Cable cable) { Serial << "Timing Clock: " << cable << endl; }
  void onStart(Cable cable) { Serial << "Start: " << cable << endl; }
  void onContinue(Cable cable) { Serial << "Continue: " << cable << endl; }
  void onStop(Cable cable) { Serial << "Stop: " << cable << endl; }
  void onActiveSensing(Cable cable) {
    Serial << "Active Sensing: " << cable << endl;
  }
  void onSystemReset(Cable cable) {
    Serial << "System Reset: " << cable << endl;
  }

} callback;

void setup() {
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midi.setCallbacks(callback);
  Control_Surface.begin();
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  Serial.begin(250000);
  calibrateFader();
}

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(mainFaderPin) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(mainFaderPin) + tolerance;
}

void loop() {
  int faderPos = analogRead(mainFaderPin);
  int totalCp =  touchSensor.capacitiveSensor(9);
  Control_Surface.loop();

  if ((faderPos == lastfaderPosition) && (totalCp <= minimumCp) && (incomingNote == 16)) {
    updateFader(incomingVelocity * 8);
    }

  if ((faderPos == lastfaderPosition) && (totalCp > minimumCp)) {
    midi.sendNoteOn({37, CHANNEL_2}, 127);
    digitalWrite(motorUp, LOW);
    digitalWrite(motorDown, LOW);
  }

  if (((faderPos < lastfaderPosition - 1) || (faderPos > lastfaderPosition + 1)) && (totalCp > minimumCp)) {
    digitalWrite(motorUp, LOW);
    digitalWrite(motorDown, LOW);
  }
  if (((faderPos < lastfaderPosition - 1) || (faderPos > lastfaderPosition + 1)) && (totalCp <=minimumCp)) {
// Stop Sending MIDI, and receive it only
  }
  lastfaderPosition = faderPos;
}

void updateFader(int position) {     //Function to move fader to a specific position between 0-1023 if it's not already there
  if (position < analogRead(mainFaderPin) - tolerance && position > faderMin) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(mainFaderPin) - tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW);
  }
  else if (position > analogRead(mainFaderPin) + tolerance && position < faderMax) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(mainFaderPin) + tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW);
  }
}
```

Note that when I use this version with an Arduino UNO, the whole thing works. I've tried discussing this with a few who are far more experienced than I, but surprisingly they were unable to provide insight as to why.

```
#include <SoftwareSerial.h> // MIDI Input
#include <MIDI.h> // MIDI Output
#include <CapacitiveSensor.h>

#define rxPin 0 // Input  (Grey)
#define txPin 1 // Output (Yellow)

SoftwareSerial midiSerial (rxPin, txPin);

const byte wiper        = 0; //Position of fader relative to GND (Analog 0)
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;
const byte touchSend    = 7;//Send pin for Capacitance Sensing Circuit (Digital 7)
const byte touchReceive = 8; //Receive pin for Capacitance Sensing Circuit (Digital 8)
unsigned int incomingCommand;
unsigned int incomingNote;
unsigned int incomingVelocity;
byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte minimumCp  = 200; // Raise if the fader is too sensitive (0-16383)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)
double faderMax = 1023; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay    = 15; // the debounce time; increase if the output flickers
int lastfaderValue    = 0;
int targetPosition;
byte ch1Vol = 176;
byte fullVel = 127;
byte ch_1 = 1;
byte Db_1 = 1;

CapacitiveSensor touch = CapacitiveSensor(touchReceive, touchSend);
MIDI_CREATE_DEFAULT_INSTANCE();

void setup() {
  touch.set_CS_AutocaL_Millis(0xFFFFFFFF);
  midiSerial.begin(31250);
  MIDI.begin();
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  calibrateFader(); }

void calibrateFader() {
  digitalWrite(motorUp, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorUp, LOW);
  faderMax = analogRead(wiper) - tolerance;
  digitalWrite(motorDown, HIGH);
  analogWrite(motorPWM, motorSpeed);
  delay(300);
  digitalWrite(motorDown, LOW);
  faderMin = analogRead(wiper) + tolerance; }

void loop() {
  int faderPos = analogRead(wiper);
  int faderHiResMIDI = ((faderPos *16.0146627566) - 8191.5);

  while ( midiSerial.available()) {
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read()*8.05511811024;
  if ((incomingVelocity  <=1023) && (incomingCommand >127) && (incomingNote <128)) {
    midiSerial.write(incomingCommand);
    midiSerial.write(incomingNote);
    midiSerial.write(incomingVelocity); } }

 { int totalCp =  touch.capacitiveSensor(30);
 if ( (millis() - lastDebounceTime) > debounceDelay) {
    if (totalCp <= minimumCp) {
      //if (incomingCommand == ch1Vol) {
        updateFader(incomingVelocity); }// }    // Not Touching fader
    if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) {
      MIDI.sendNoteOn(Db_1, fullVel, ch_1); // Touching Fader
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    if (((faderPos > lastfaderValue+1) or (faderPos < lastfaderValue-1)) && (totalCp > minimumCp)) {   // Moving Fader
      MIDI.sendPitchBend(faderHiResMIDI, ch_1);
      digitalWrite(motorDown, LOW);
      digitalWrite(motorUp, LOW); }
    lastfaderValue = faderPos;
    lastDebounceTime = millis(); } } }

void updateFader(int position) {     //Function to move fader to a specific position between 0-1023 if it's not already there
  if (position < analogRead(wiper) - tolerance && position > faderMin) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(wiper) - tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW); }
  else if (position > analogRead(wiper) + tolerance && position < faderMax) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(wiper) + tolerance) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW); } }
```

body:
**Firstly,** you need a robust way to synchronise to and parse MIDI messages which can be 1 byte, 2 bytes or 3 bytes or more... See this [Summary of MIDI 1.0 Messages][1] by the [MIDI Association][2].

A good way to achieve this is by using a state machine. I've written a simple one below that parses 3-byte MIDI messages. It could be expanded to parse different types of commands.

```cpp
typedef enum State
{
    Idle,
    Command,
    Data1
};

State state = State::Idle;

const float INCOMING_VELOCITY_SCALE = 1023.0 / 127.0;

byte incomingCommand;
byte incomingNote;
byte incomingVelocity;

int targetPosition;

void loop()
{
    if (midiSerial.available())  // Use the `if` statement to get the next available byte.
    {
        byte incoming = midiSerial.read();

        // Synchronise to and parse the 3-byte MIDI message packet, i.e. 1nnnnnnn 0nnnnnnn 0nnnnnnn
        switch (state)
        {
        case State::Idle:
            if (IsMidiCommand(incoming))
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data byte.");
            }
            break;
        case State::Command:
            if (IsMidiCommand(incoming))  // Double check for an out of sync command.
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data1 byte.");
                incomingNote = incoming;
                state = State::Data1;
            }
            break;
        case State::Data1:
            if (IsMidiCommand(incoming))  // Triple check for an out of sync command.
            {
                Serial.println("Received command byte.");
                incomingCommand = incoming;
                state = State::Command;
            }
            else if (IsMidiData(incoming))
            {
                Serial.println("Received data2 byte.");
                incomingVelocity = incoming;
                midiSerial.write(incomingCommand);
                midiSerial.write(incomingNote);
                midiSerial.write(incomingVelocity);
                Serial.write(incomingCommand);
                Serial.write(incomingNote);
                Serial.write(incomingVelocity);
                Serial.println();
                targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
                if (targetPosition > faderMax)      // Clip if out of bounds.
                {
                    targetPosition = faderMax;
                }
                else if (targetPosition < faderMin)
                {
                    targetPosition = faderMin;
                }
                state = State::Idle;
            }
            break;
        default:
            state = State::Idle;
            break;
        }
    }
    . . .
    updateFader(targetPosition);
    . . .
}

bool IsMidiCommand(const byte b)
{
    return b >= 128;  // For MIDI command bytes, MSB is 1.
}

bool IsMidiData(const byte b)
{
    return b <= 127;  // For MIDI data bytes, MSB is 0.
}
```

**Secondly,** there is an issue with the `updateFader()` function regarding the `tolerance`. It's `40` in your first version and `10` in your second version. Consider the following values for the variables:

```cpp
// In setup()
digitalWrite(motorDown, HIGH);
analogWrite(motorPWM, motorSpeed);
delay(300);
faderMin = analogRead(wiper) + tolerance;
faderMin = 0                 + 40;         // Bottom of range.
faderMin = 40;

// In loop()
incomingVelocity = midiSerial.read() * 8.05511811024;
incomingVelocity = 1                 * 8.05511811024;  // A quiet note, e.g. between 0 and 5, will a give a value of 0 to 40.
incomingVelocity = 8;

// In updateFader()
if (position < analogRead(wiper) - tolerance && position > faderMin)
if (8        < 512               - 40        && 8        > 40      )
if (8        < 472                           && 8        > 40      )
if (true                                     && false              )
if (false                                                          )
```

Result: the fader will not budge if a quiet note is received that puts `position` below `faderMin` and will leave the fader jamming somewhere in the middle of its scale rather than boogieing on down to `faderMin`. This effect would be exaggerated if `faderMin` were higher than 40 when `analogRead(wiper)` reads greater than zero in `setup()`.

Similarly, this also happens with very loud notes and `faderMax` at the other end of the scale:

```cpp
// In updateFader()
else if (position > analogRead(wiper) + tolerance && position < faderMax)
```

A better way would be to clip the `targetPosition` to the valid range before calling `updateFader()` and remove the second condition from the `if` statements in `updateFader()`:

```cpp
targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
if (targetPosition > faderMax)      // Clip if out of bounds.
{
    targetPosition = faderMax;
}
else if (targetPosition < faderMin)
{
    targetPosition = faderMin;
}
. . .
updateFader(targetPosition);
. . .
if (position < analogRead(wiper) - tolerance)
. . .
else if (position > analogRead(wiper) + tolerance)
. . .
```

**Thirdly,** `updateFader()` blocks until the fader motor has finished moving. If notes are being received faster than the fader can move, the tempo will rallentando, so consider using a non-blocking style like [Blink Without Delay][3].

**Fourthly,** `faderMin` and `faderMax` should be just that – the minimum and maximum extent of fader travel. But by adding/substracting `tolerance` from min/max it is unnecessarily reducing the range. The tolerance is effectively being doubled by adjusting for it in *both* `setup()` *and* `adjustFader()`. The extent of fader travel can be obtained by taking an average of several values in `calibrateFader()`. Then the tolerance can be adjusted for only once in `adjustFader()` as described above.

```cpp
void calibrateFader()
{
    const byte NUM_SAMPLES = 10;
    digitalWrite(motorUp, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorUp, LOW);
    faderMax = AnalogueAverage(wiper, NUM_SAMPLES);
    Serial.println(faderMax);
    digitalWrite(motorDown, HIGH);
    analogWrite(motorPWM, motorSpeed);
    delay(300);
    digitalWrite(motorDown, LOW);
    faderMin = AnalogueAverage(wiper, NUM_SAMPLES);
    Serial.println(faderMin);
}

unsigned int AnalogueAverage(const byte pin, const byte num_samples)
{
    const byte ROUND_OFF = num_samples / 2;
    unsigned long total = 0;
    for (byte i = 0; i < num_samples; i++)
    {
        total += analogRead(pin);
    }
    return (total + ROUND_OFF) / num_samples;
}
```

On a different note...
===

...I've been reading through the documentation and source code for the libraries you referenced in your code, which I think are these ones:
1. [Control Surface][4]
2. [Arduino MIDI Library][5]

These already implement the MIDI message parsing using callbacks, e.g.:
 - [Using callbacks][6]
 - [Using callbacks .ino][7]

That example stresses the importance of swift non-blocking code. This means that `updateFader()` should also be non-blocking. You have the option to write your own custom state machine parser or use the libraries' parsers.

Here is how your code could be re-written to use the MIDI library's parser with non-blocking callbacks and non-blocking `updateFader()`. You may want to double-check which pins you are using for `midiSerial` because pins 0 and 1 are used for the default Serial monitor or you could use `MIDI.sendNoteOn()` and `MIDI.sendNoteOff()`.

```cpp
#include <MIDI.h>

MIDI_CREATE_DEFAULT_INSTANCE();

unsigned int faderMax = 0;
unsigned int faderMin = 0;
unsigned int faderTargetPosition = 0;

void doNoteOn(byte channel, byte note, byte velocity)
{
    midiSerial.write(channel);
    midiSerial.write(note);
    midiSerial.write(velocity);
    faderTargetPosition = velocity * INCOMING_VELOCITY_SCALE;

    // Clip if out of bounds.
    if (faderTargetPosition > faderMax)
    {
        faderTargetPosition = faderMax;
    }
    else if (faderTargetPosition < faderMin)
    {
        faderTargetPosition = faderMin;
    }
}

void doNoteOff(byte channel, byte note, byte velocity)
{
    midiSerial.write(channel);
    midiSerial.write(note);
    midiSerial.write(velocity);
}

void setup()
{
    MIDI.setHandleNoteOn(doNoteOn);
    MIDI.setHandleNoteOff(doNoteOff);
    MIDI.begin(MIDI_CHANNEL_OMNI);
    . . .
}

void loop()
{
    // Parse the MIDI messages and call the callbacks.
    MIDI.read();

    if ((millis() - lastDebounceTime) > debounceDelay)
    {
        int totalCp = touch.capacitiveSensor(30);
        int faderPos = analogRead(FADER_PIN);
        int faderHiResMIDI = faderPos * 16.0146627566 - 8191.5;

        if (totalCp <= minimumCp)
        {
            // Not touching fader.
            //if (incomingCommand == ch1Vol)
            //{
            updateFader(faderTargetPosition);
            //}
        }
        else
        {
            if (faderPos == lastfaderValue)
            {
                // Touching fader.
                MIDI.sendNoteOn(Db_1, fullVel, ch_1);
                digitalWrite(MOTOR_DOWN_PIN, LOW);
                digitalWrite(MOTOR_UP_PIN, LOW);
            }
            else if ((faderPos > lastfaderValue + 1) or (faderPos < lastfaderValue - 1))
            {
                // Moving fader.
                MIDI.sendPitchBend(faderHiResMIDI, ch_1);
                digitalWrite(MOTOR_DOWN_PIN, LOW);
                digitalWrite(MOTOR_UP_PIN, LOW);
            }
        }
        lastfaderValue = faderPos;
        lastDebounceTime += debounceDelay;  // Constant interval.
    }
}

void updateFader(const unsigned int& faderTargetPosition)
{
    const unsigned int currentPosition = analogRead(FADER_PIN);
    if (faderTargetPosition < currentPosition - tolerance)      // Below the tolerance band.
    {
        digitalWrite(MOTOR_UP_PIN, LOW);                        // Switch the up control off before switching the down control on.
        digitalWrite(MOTOR_DOWN_PIN, HIGH);
    }
    else if (faderTargetPosition > currentPosition + tolerance) // Above the tolerance band.
    {
        digitalWrite(MOTOR_DOWN_PIN, LOW);                      // Switch the down control off before switching the up control on.
        digitalWrite(MOTOR_UP_PIN, HIGH);
    }
    else                                                        // Within the tolerance band.
    {
        digitalWrite(MOTOR_DOWN_PIN, LOW);
        digitalWrite(MOTOR_UP_PIN, LOW);
    }
}
```

  [1]: https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message
  [2]: https://www.midi.org/
  [3]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay
  [4]: https://github.com/tttapa/Control-Surface
  [5]: https://github.com/FortySevenEffects/arduino_midi_library
  [6]: https://github.com/FortySevenEffects/arduino_midi_library/wiki/Using-Callbacks
  [7]: https://github.com/FortySevenEffects/arduino_midi_library/blob/master/examples/Callbacks/Callbacks.ino


message:
Arduino Serial Monitor Input 3DES Encryption

I am trying to 3DES encryption using Serial Read, Found this 3DES Sample code in Github,

    #include <DES.h>
    DES des;
    void setup() {
      Serial.begin(9600);
      Serial.println("Hello!");
    }
    void loop() {
      desTest();
      tdesTest();
      delay(2000);
    }
    void desTest()
    {
      byte out[8];
      byte in[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
      byte key[] = { 0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e };

      Serial.println();
      Serial.println("========= DES test ==========");

      //encrypt
      Serial.print("Encrypt...");
      unsigned long time = micros();
      des.encrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);

      //decrypt
      for (int i = 0; i < 8; i++)
      {
        in[i] = out[i];
      }
      Serial.print("Decrypt...");
      time = micros();
      des.decrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);
    }
    void tdesTest()
    {
      byte out[8];
      byte in[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
      byte key[] = {
                      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
                      0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
                      0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
                    };

      Serial.println();
      Serial.println("====== Triple-DES test ======");

      //encrypt
      Serial.print("Encrypt...");
      unsigned long time = micros();
      des.tripleEncrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);

      //decrypt
      for (int i = 0; i < 8; i++)
      {
        in[i] = out[i];
      }
      Serial.print("Decrypt...");
      time = micros();
      des.tripleDecrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);
    }
    void printArray(byte output[])
    {
      for (int i = 0; i < 8; i++)
      {
        if (output[i] < 0x10)
        {
          Serial.print("0");
        }
        Serial.print(output[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }

I want to get user serial input from Serial Monitor to feed `byte in[]`. Which will encrypt user input, I will pad user input to 8 Bytes or restrict input to 8.

Library: [https://github.com/Octoate/ArduinoDES][1]

Could any one help me to get data from user input.

**Edit 1: I was able to read the String to char and feed to `byte in[]` changed the code,**

    #include <DES.h>
    DES des;

    String  input;

    char buf[30];
    void setup() {
      Serial.begin(9600);
      Serial.println("Hello!");

    }

    void printArray(byte output[])
    {
      for (int i = 0; i < 8; i++)
      {
        if (output[i] < 0x10)
        {
          Serial.print("0");
        }
        Serial.print(output[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }
    void loop() {

      while (Serial.available() > 0) {

        String  input = Serial.readString(); // read the incoming data as string
        char buf[30];
    /*
        input.toCharArray(buf, 9);
        Serial.println(buf);
    */
        input.toCharArray(buf, input.length() + 1);
        Serial.println(buf);

        byte out[8];
        byte in[] = {buf};
        Serial.println(buf);
        byte key[] = {
          0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
          0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
          0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
        };

        Serial.println();
        Serial.println("====== Triple-DES test ======");

        //encrypt
        Serial.print("Encrypt...");
        unsigned long time = micros();
        des.tripleEncrypt(out, in, key);
        time = micros() - time;
        Serial.print("done. (");
        Serial.print(time);
        Serial.println(" micros)");
        printArray(out);

        //decrypt
        for (int i = 0; i < 8; i++)
        {
          in[i] = out[i];
        }
        Serial.print("Decrypt...");
        time = micros();
        des.tripleDecrypt(out, in, key);
        time = micros() - time;
        Serial.print("done. (");
        Serial.print(time);
        Serial.println(" micros)");
        printArray(out);
        delay(2000);
      }

    }

But I don't think getting the correct,
Please find the below,
[![enter image description here][2]][2]

But when I feed manually like below,

    ...
    input.toCharArray(buf, input.length() + 1);
        Serial.println(buf);

        //tdesTest();
        byte out[8];
        byte in[] = {"12345678"}; //Manually feeding hardcoding the value need to get the value from serial read to here
        Serial.println(buf);
        byte key[] = {
          0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
          0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
          0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
        };

        Serial.println();
        Serial.println("====== Triple-DES test ======");
    ...

I get the expected output,

[![enter image description here][3]][3]

  [1]: https://github.com/Octoate/ArduinoDES
  [2]: https://i.stack.imgur.com/xmy6N.jpg
  [3]: https://i.stack.imgur.com/tFmBa.jpg

body:
From your comments I *think* I understand what you are after.  So, assuming you have read some string into a `String` object called `input` and you have an array `in[8]` to populate you can:

1. Clear the `in[]` array to a preset state
2. Copy the string content into `in[]`

As code:

```c++
memset(in, 0, 8); // Erase the contents of in[]
input.toCharArray((char *)in, 8); // Copy up to 8 bytes from the string
```


body:
    #include <DES.h>
    DES des;
    byte in[8];
    String  input;

    char buf[30];
    void setup() {
      Serial.begin(9600);
      Serial.println("Hello!");

    }

    void tdesTest() {
      byte out[8];

      byte key[] = {
        0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key A
        0x92, 0x2f, 0xb5, 0x10, 0xc7, 0x1f, 0x43, 0x6e, // key B
        0x3b, 0x38, 0x98, 0x37, 0x15, 0x20, 0xf7, 0x5e, // key C (in this case A)
      };

      Serial.println();
      Serial.println("====== Triple-DES test ======");

      //encrypt
      Serial.print("Encrypt...");
      unsigned long time = micros();
      des.tripleEncrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);

      //decrypt
      for (int i = 0; i < 8; i++)
      {
        in[i] = out[i];
      }
      Serial.print("Decrypt...");
      time = micros();
      des.tripleDecrypt(out, in, key);
      time = micros() - time;
      Serial.print("done. (");
      Serial.print(time);
      Serial.println(" micros)");
      printArray(out);
      delay(2000);
    }

    void printArray(byte output[])
    {
      for (int i = 0; i < 8; i++)
      {
        if (output[i] < 0x10)
        {
          Serial.print("0");
        }
        Serial.print(output[i], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }

    void loop() {

      while (Serial.available() > 0) {

        String  input = Serial.readString(); // read the incoming data as string
        memset(in, 0, 9); // Erase the contents of in[]
        input.toCharArray((char *)in, 9); // Copy up to 8 bytes from the string
        tdesTest();

      }
    }