text:
Can’t set duty cycle to 0% with custom PWM
I'm trying to control a heating element with PWM with an Arduino Nano, but the problem is even if I set the duty cycle to 0 it gives a tiny spike.
I want to generate a square wave of 1Hz and that's why I override the default PWM registers.
Here is the code:
// Set up fast PWM on the Arduino Uno at 1 Hz on digital pin D9
void setup() {

    // set I/O pins
    pinMode(LDR_INPUT, INPUT);      // A0
    pinMode(HEATER_OUTPUT, OUTPUT); // D9

    // Enable the PWM output OC1A on digital pins 9
    TCCR1A = _BV(COM1A1) | _BV(WGM11);
    // Set fast PWM and prescaler of 256 on timer 1
    TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS12);
    // Set the PWM frequency to 1Hz: 16MHz/(256 * 1Hz) - 1 = 62499
    ICR1 = 62499;

    // OCR1A = 32149; // this gives me duty cycle of 50%, working fine

    OCR1A = 0;       // but this is not working

    //allow PWM timers to start
    delay(10);
}

For testing, I connected an LED to the PWM pin (D9) and these are the spikes from the LDR reading from analog pin A0 (I don't have an oscilloscope).

I'm getting the same results with the Nano and Uno. My IDE version is 1.8.14.
How can I fix this problem?
Here is my temperature control function:
void Compute()
{
    unsigned long now = millis();
    int timeChange = (now - lastTime);

    if(timeChange>=SampleTime)
    {
        /*Compute all the working error variables*/
        double error = Setpoint - temprature;

        if (error <= 0)
        {
            Output = 0;
            Serial.println("level: 0");
        }
        else if (error <= 1)
        {
            Output = 5;
            Serial.println("level: 1");
        }
        else if (error <= 2)
        {
            Output = 30;
            Serial.println("level: 2");
        }
        else if (error <= 3)
        {
            Output = 50;
            Serial.println("level: 3");
        }
        else if (error <= 10)
        {
            Output = 60;
            Serial.println("level: 4");
        }
        else if (error <= 100)
        {
            Output = 200;
            Serial.println("level: 5");
        }
        else
        {
            Output = 255;
            Serial.println("level: 6");
        }

        analogWrite(HEATER_OUTPUT, Output);
        //OCR1A = map(Output, 0, 255, 0, 62499);
        delay(10);

        lastErr = error;
        lastTime = now;
    }
}

The problem is that after I override the PWM registers, the analogWrite() seems messed up. It's not working, and for all the values of Output, the result is almost the same.
UPDATE 22/06/2021
I'm still struggling to fix this, if I use analogWrite() or digitalWrite() to turn off the PWM pin, the further changes on OCR1A regs are not taking action. whatever values I gave to the OCR1A the pin remains low, if I manually make the pin high with digitalWrite or analogWrite the pin remains high forever the changes on OCR1A are not taking into action.
I wrote a test function
void testPWM3() {

    Serial.println("f: 1Hz | on 0s");
    digitalWrite(HEATER_OUTPUT, LOW); // turn off the pwm pin to get full of (0% duty cycle)
    delay(5000);
    /*
     After turning off the pin with digitalWrite() further changes on OCR1A reg are not taken into action
    */
    digitalWrite(HEATER_OUTPUT, HIGH);
    Serial.println("f: 1Hz | on 125ms");
    OCR1A =  1953;
    delay(5000);

    Serial.println("f: 1Hz | on 250ms");
    OCR1A =  3906;
    delay(5000);

    Serial.println("f: 1Hz | on 500ms");
    OCR1A =  7812;
    delay(5000);

    Serial.println("f: 1Hz | on 1sec");
    digitalWrite(HEATER_OUTPUT, HIGH);  // this works
    delay(5000);
}

Any advice on this will be greatly helpful, thank you

That is how it is supposed to be. In this fast PWM mode, the duty cycle
is (OCR1A+1)/(ICR1+1). If you want a duty cycle of zero, you have to
disengage the PWM and turn the pin to OUTPUT LOW.
This is what the Arduino's analogWrite() does: it treats the
value 0 as a special case. Note that 255 is also treated as a special
case, although that is not useful.
Edit 1: about analogWrite() being messed up.
analogWrite(9, value) sets OCR1A to a value between 1 and 254 (0 and
255 being handled in a different manner). The duty cycle you get is, as
I wrote before (OCR1A+1)/(ICR1+1). This is not what your test
function expects.
I suggest you ditch analogWrite() and instead set directly OCR1A.
Edit 2: Once you have taken control of a PWM channel at low-level,
by writing directly to the hardware registers, you should not use
the Arduino functions digitalWrite() nor analogWrite() on the
associated pin. These functions assume those hardware registers are
controlled solely by the Arduino core, and they will fiddle with them in
a way that will likely break your program.
To set the duty cycle to zero, disable the PWM mode and set the pin to
LOW:
TCCR1A &= ~_BV(COM1A1);  // disable PWM on pin OC1A = PB1
PORTB  &= _BV(PB1);      // set PB1 to LOW

Thank you for your response, I have tried that, but the analogWrite is not working properly in my case, updated the question.

You mean not working properly in a way different from how this answer explains perfectly well?

@timemage, this is a great answer, I got what he says, with analogWrite()  I'm getting clean off PWM, but with analogWrite(9,128) I'm supposed to get a duty-cycle of 50%, but what I'm getting is a really thin pulse..

Re “analogWrite(9,128) I'm supposed to get a duty-cycle of 50%”: No, you are not. Read my answer more carefully.

oh damn me, so for getting 50% I have to give half of ICR1 right..?

Hi, there I'm still struggling to fix this, if I use analogWrite() to turn off the PWM pin, the further changes on OCR1A regs are not taking action. whatever values I gave to the OCR1A the pin remains low, if I manually make the pin high with digitalWrite or analogWrite the pin remains high forever the changes on OCR1A are not taking into action... Any advice on this will be greatly helpful, thank you

Fast PWM works that way, on Duty Cycle 0% the Output is set to high for 1 cycle at TOP+1 for non-inverted PWM mode and to low for inverted mode.
If you want to have a continuous low output, you have to use Phase Correct  or Phase and Frequency Correct PWM.


text:
How to set 16x2 LCD I2C display backlight?
I have 16x2 LCD display with a I2C backpack. This is the library I am using
https://drive.google.com/drive/folders/16_UqfwFm4VKWcdeJfDmHRV2Hj_IoaTai?usp=sharing
So as given in the code below, by changing variable back to a 0 or 1, I can turn on and off the backlight. However if I change the values of back to 100, or 50 the backlight does not get affected, how do I make this happen without the need of an external resistor/potentiometer and but with code.
Note that on my backpack, there is no connection between pins A and K to keep the backlight on but if I connect the two, then the backlight is turned off.
If you don't care of the above here's it summarized-
How do I control Backlight of LCD with I2C backpack through code?
Code-
#include "LiquidCrystal_PCF8574.h"
#define LCD_ADDRESS 0x27
#define LCD_ROWS 2
#define LCD_COLUMNS 16
#define SCROLL_DELAY 150
int back = 1; // 1-on, 0-off

LiquidCrystal_PCF8574 lcdI2C;

void setup(){
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);
}

void loop(){
delay(1000);
back = 0;
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);
delay(1000);
back = 1;
lcdI2C.begin(LCD_COLUMNS, LCD_ROWS, LCD_ADDRESS, back);

}

You don't.  The PCF8574 is an IO expander. It doesn't have any provision for PWM. It's either on, or off.

Ok, kinda disappointing, but good to know

Can I just use analog write and connect that pin to Pin A on the lcd?

@Coder9390, if you want to do that, you should probably interpose a transistor.  The backlight current is typically more than you'd want going through an Arduino I/O pin.

....and then use PWM on the transistor right

Note that on my backpack, there is no connection between pins A and K to keep the backlight on but if I connect the two, then the backlight is turned off. -- Sounds like you're short circuiting the back light there.

No, I had my doubts but when I connect the 2 nothing happens

In the sense that the backlight turns off and nothing blows up or heats up

If there is a resistor in the circuit between the PCF and the LCD then I wouldn't expect anything bad to happen.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Deepsleep ESP8266 Thing
I have been trying to get my ESP8266 Thing to go to sleep. Power LED has been disconnected. Problem is that the current consumption is initially (briefly) ~78 uA, but nearly always jumps up to ~540 uA for the remainder of the sleep duration. See below. It's as though something is waking up when it shouldn't. Has anyone else experienced this? Any ideas or suggestions?
Thanks in advance :)

#include <Ticker.h> // Ticker can periodically call a function
Ticker blinker; // Ticker object called blinker.

int ledPin = 5; // LED is attached to ESP8266 pin 5.
uint8_t ledStatus = 0; // Flag to keep track of LED on/off status
int counter = 0; // Count how many times we've blinked

void setup()
{
  pinMode(ledPin, OUTPUT); // Set LED pin (5) as an output
  blinker.attach(0.25, blink); // Ticker on blink function, call every 250ms
}

void loop()
{

}

void blink()
{
  if (ledStatus)
    digitalWrite(ledPin, HIGH);
  else
    digitalWrite(ledPin, LOW);
  ledStatus = (ledStatus + 1) % 2; // Flip ledStatus

  if (counter++ > 20) // If we've blinked 20 times
    ESP.deepSleep(60000000, WAKE_RF_DEFAULT); // Sleep for 60 seconds
    //ESP.deepSleep(60000000); // Sleep for 60 seconds
    delay(10);
}

If I'm not mistaken, the longest ESP8266 sleep time is only in the minutes (far less than an hour).  So, is saving about 500 uAmps between wake-ups add up to much when compared to the average current over, say, an hour?

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Custom LED toggling function: one out of three LEDs misbehave
I connected three LEDs to an Arduino Uno and wrote a simple LED class. I toggle all the leds the main loop, but for some reason one led (connected to pin7) always misbehaves, skips one toggle or stays on all the time. Initially all leds are off (in begin() function). What could cause this problem?
main.cpp
#include "led.h"
#include <Arduino.h>

Led leds[] = {
    Led(2),
    Led(3),
    Led(7)
};

void setup()
{
    Serial.begin(9600);
    for (Led& l : leds) l.begin();
}

void loop()
{
    for (Led &l : leds) l.toggle();
    delay(500);
}

Led.h
class Led {
public:
    Led(int pin);
    void begin();
    void toggle();

private:
    const int _pin;
};

Led.cpp
#include "led.h"
#include "Arduino.h"

Led::Led(int pin) : _pin(pin)
{}

void Led::begin()
{
    pinMode(_pin, OUTPUT);
    digitalWrite(_pin, LOW);
}

void Led::toggle()
{
    digitalWrite(_pin, !digitalRead(_pin));
}

Check the wiring; there's no particular reason this would be an issue specifically with that pin unless there's a wiring or electrical issue (which can be internal). Note that digitalRead returns an int, not a bool, and IMO should be coded as such to avoid breaking changes or cross-architecture issues.

Aha okay, the Arduino I'm using has been through alot so I will verify this with a new one soon. It could be faulty. But what exactly do you mean that "it should be coded as such"? Should I explicitly cast it to a bool? Or write it the "long way", checking if digitalRead==0 or ==1?

Re: the latter; it's (incrementally) safer to check against HIGH (or LOW) and use a conditional op. I forget the thread that led me to think this could be a potential issue moving forward--something on the Arduino forums. Sorry--it's probably not a big deal, either.

Got cranky and found it: https://forum.arduino.cc/t/does-digitalread-on-an-output-pin-return-the-last-state-it-was-set-to/437863

It's safer for your class to have an internal record of the LED state instead of relying on digitalRead() to give you the right result.

Okay, I was considering this option as well. Could you point me to some resources or explanations what is the reasoning behind it? What do you mean by "safer"?

It seems to be a hardware fault, as others have suggested:
I connected the LED to another pin(8) and it works perfectly, everytime.
Looks like something got fried internally on that specific pin


text:
Help to set vertical dcroll on SSD1306
I am trying to set the text to scroll vertically. I have a big chunk of text (example in the code below) to be set to scroll vertically. What I want is to display the complete text on the screen. Presently it scrolls the complete chunk of text. Any help or guidance is heartily welcome.
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
// On an arduino UNO:       A4(SDA), A5(SCL)
// On an arduino MEGA 2560: 20(SDA), 21(SCL)
// On an arduino LEONARDO:   2(SDA),  3(SCL), ...
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3D ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
  Serial.begin(9600);
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0, 0);
  display.println("Sometimes we dont want to scroll entire display. ");
  display.startscrollright(0x00, 0x0F);

  display.display();

  delay(1000);
}
void loop(){

}

The link to the project is here: https://wokwi.com/arduino/projects/302023407584674313
3rd edit
My question:
My goal is to display the text in the window. The text should not go out of the window.  If the text is too long, it should scroll vertically.
Thanks again, everyone.

I'm not 100% sure what you're asking; your text mentions vertical scrolling, your code does horizontal scrolling of 16 rows, and your text presumably is much wider than the screen. Can you edit the question to be more clear?

So you don't want to scroll, you want to wrap the text?

So... you've abandoned the question about scrolling and instead want to just render some text as large as possible on the screen?

@DaveNewton timemage The whole text should be fit in the screen., It need not become large., It has to be scrollable, when the test is more than what the device can display

The whole text can't fit on the screen--are you saying if the text is larger than the screen it should automatically scroll?

Dear @DaveNewton yes. exactly

And what is the current issue? You may also want to update your question to reflect the information from these comments, because the question asks about vertical scrolling.

okay. I will update the question clearly soon

This line achieved it for me. I stole it from here: Adafruit Forum
display.startscrolldiagright(0x0F, 0x0F);

It sets diagonal scroll, but start and stop positions are multiples of the display width so that in total, it scrolls vertically up.
Alternatively, you edit the display buffer; by removing your content from the current position, deleting the first line of pixels, adding a new last line of pixels, writing it all back to the display buffer and then call display.display().
This is not exactly saving your microcontroller time but it works, too. I asked ChatGpt to do the coding for the second solution, it delivered. I won't post the code here though, as it is against the rules.


text:
How do I read from a correct data address of LIDAR using Arduino in I2C?
I need to read the distance data from a lidar in I2C using an Arduino Nano. Currently, this is the code I've written.
unsigned int readDistance()
{
  unsigned int dist = 0 ; // LiDAR actually measured distance value. static so we can return previous dist

  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(0x10) ; // transmit to device 0x10
  Wire.write(2) ; // sets distance data address (addr)
  Wire.write(3) ; // sets distance data address (addr)
  Wire.endTransmission() ; // stop transmitting

  // step 2: wait for readings to happen
  delay(100) ; // datasheet suggests at least 100ms

  // step 3: request reading from sensor
  Wire.requestFrom(0x10, 2) ; // request 2 bytes (DIST_L, DIST_H) from slave device #0x10
  dist = Wire.read() ; dist += Wire.read() << 8; // calculate distance value, bit shift high distance
  return dist ; // return updated dist
}

But I have a feeling I'm requesting from the wrong data address', since I'm not getting the results I expect (ie. varying distance data). Furthermore, I used an I2C scanner which 100% confirms the lidar is on the (default address) of 0x10.
Datasheet of (TF02 Pro): https://www.unmannedtechshop.co.uk/wp-content/uploads/2020/01/TF02-Pro-Product-Manual-Alpha.pdf
Question: am i reading from the right data address
Any help would be appreciated.

which information on which page are you following?

i'm quite new to arduino so please bear with me. are you talking about the datasheet for the lidar which I'm getting the address' from? that's @ https://www.unmannedtechshop.co.uk/wp-content/uploads/2020/01/TF02-Pro-Product-Manual-Alpha.pdf

It looks to me like you have to send the same things through i2c as you would through UART. It's not your typical i2c device.

What results are you getting exactly? If your code is not stalling or failing then I doubt it’s an address issue.
Do you maybe have access to an oscilloscope or I2C test device  to see what’s happening on the I2C bus?

Long story short, some i2c devices are configured such that data is only present in said registers after continually issuing 'read commands'.
In this case, the read command was: 5A 05 00 01 60
Amended code:
unsigned int readDistance()
{
  unsigned int dist = 0 ; // LiDAR actually measured distance value

  // step 1: instruct sensor to read echoes
  Wire.beginTransmission(0x10) ; // transmit to device 0x10
  Wire.write(0x5A) ; // some read command.
  Wire.write(0x05) ;
  Wire.write(0x00) ;
  Wire.write(0x01) ;
  Wire.write(0x60) ;
  Wire.endTransmission() ; // stop transmitting

  // step 2: wait for readings to happen
  delay(100) ; // datasheet suggests at least 100ms

  // step 3: request reading from sensor
  Wire.requestFrom(0x10, 4) ; // request first 4 bytes from slave device #0x10
  Wire.read() ; Wire.read() ; //ignore header bytes
  // remaining two bytes for distance (DIST_L, DIST_H)
  dist = Wire.read() ; dist += Wire.read() << 8 ; // calculate distance value, bit shift high distance
  return dist ; // return updated dist
}


text:
My Arduino UNO works, but 2 smd overheats. Why?
I can use my Arduino with the usb plug, but 2 smd overheating when I plug into the computer, But when I use the DC plug, the leds on the Arduino barely visible (for example the "ON" led), so the arduino is only works with the USB plug.

These look like C2 and C3 in the Arduino UNO R3 schematic. It sounds like both are internally shorted.
Assuming that's true, why it would work (partially anyway) on USB but not external power would depend in part on what external voltage had been applied.  The voltage seen on the board, and therefore the brightness of your LEDs, depends on the voltage being dropped above their source.  That is, it depends on what's happening to the PTC fuse and in the USB host port and cable etc for USB.  And in the linear regulator and similar current limiting in series with it.  Probably the thermal overload protection in your regulator is shutting it down so hard that the LEDs don't even light.  Or whatever event cause this problem happened while you were externally powering it and there's now an open somewhere on the side external powering.
For now it's probably better if you're not continuing to plug it into a PC.  If you're going to do that, it's probably better that you have a powered hub that you don't care about in between.
This seems to be the 3.3V regulator.  If you're not using 3.3V, you may be able to get a soldering iron and through-heat the capacitors and scrape them off the board and see whether or not the rest of the board, the 5V section, works fine.  Before you do that you may want to measure the 5V and 3.3V lines and write down what you get.  One or both are probably low.  Take note of the USB source you're using.  Try taking off the capacitor off the output side of the regulator first, see how things go.  Then go for the input side one.  From the sounds of it both are bad though.  But it can't hurt to go methodically.

I checked the 3.3V and the 5v line too. There's a short circuit between the 3.3V and the ground line, but there is no such problem at 5 volts

3V3 is used also as a reference voltage for disconnecting Vusb when you connect something over 6.6V to barrel jack so it's not back powering anything (if you shut down the connected computer, it could be an issue, same as short on 3V3 and it can't detect anything properly)

Yeah, if it removing the caps makes the regulator unstable enough, it could be a problem.  I'm gathering from the description that the regulator is not shorted; I've yet to see one do that so well (so bad?) that it didn't make itself apparent in heat.  I'd try removing the 3.3v output-side cap first and see how thing change.

With respect to the 5V line not being shorted, well, it is possible for things to be shorted well enough for small components to get very hot but not enough to bog down the 5V/USB voltage.  I had a Leonardo where I'd managed to get about 30VDC onto one of its GPIO pins.  There after it "worked" but ran so hot you could fry an egg on the 32u4 and VUSB was able to keep up just fine.  I've since replaced the IC.  When you clear the fault you may not see any increase in voltage, but I suspect you'd see it change by at least a few mV.


text:
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?

what baud rate do you have set in Serial Monitor?

Did the upload complete successfully? To upload, GPIO pin is required to be pulled HIGH; was it? A diagram showing how your ESP was connected for both programming and testing would help. About jamming the WiFi, could your PC see any WiFis? Do you have any other WiFi devices, and how were they affected? The more information you can provide, the better someone can help you find out what happened (or didn't happen).

@Juraj No matter which baud rate, there is nothing on the serial monitor.

@JRobert IDE said that it's uploaded successfully. Instructions stated that GPIO-0 connected to ground. Now I connected it to 3.3V, unable to upload new codes.

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

I'm not sure what you mean by "jamming"; if you mean your computer auto-connects to the ESP, you can disable auto-connect on your computer. There's no issue w/ having multiple networks in the same room, though :)

The only way I've found to interpret this that could make sense is that you created a network with the same SSID as your existing network, such that some clients connected to ESP8266 when they should have been connecting to the proper network.

@timemage, with that sketch? AP starts by default on esp. esp with wrong content of RF calibration data area on flash can disturb other WiFi networks. it usually adjusts after a few resets. but it is better to clear the RF calibration data.

@Juraj, I have no idea what you're talking about.


text:
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:
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.

"ImportError: No module named serial"

Install python3-serial

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

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

I did both, it still shows the following error

I made it work, thank you for the help


text:
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?

Kinda late comment, but I'm surprised that more people haven't asked this question before, similar to how MANY people have asked about millis...

Input pin working-
An input pin on an arduino board uses something called   Tristate buffer 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?

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:

simulate this circuit – Schematic created using CircuitLab
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.


text:
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:

Create arrays for each variable (X, Y, Z, elapsedTime)
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.
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.
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");
    }
  }
}

Can you be more specific regarding "does not run properly"? In any case, there's this, this, and this. Without knowing what the issue/s with arrays is/are it's hard to help.

How about writing to external memory such as RAM or Ferroelectric RAM. That will take it as fast as you can write it, there is no write delay. Then when the test if finished transfer it to the SD card. The Ferroelectric RAM will remember even if the power is off.

Have you considered writing a binary file instead of text?

Why not writing a whole string of data at one time ?  "faster" ?

@DaveNewton Thank you for the links. The third one is especially helpful for me. The link recommends executing the SD.open and SD.close command outside the loop. However if I try to do that, this goes back to my "not run properly" statement as the program seems to go through one cycle and never repeat. I'm not really sure why this is? I figure the file should be able to be opened in setup and closed at any time you really want, and while the file is open, new data can be brought in, manipulated, and written. Does having a file open stop other functions or prevent looping? Thank you

@Gil Hey Gil, appreciate the info on FRAM. Unfortunately, I don't think using that will solve my problem as I believe this is more a problem with my code being slow. I will keep that in mind for the future though.

@jsotola I didn't even notice. When I merged two example programs together to make this, I must have left it in there by mistake. Removed from the code as of now.

@EdgarBonet I would consider doing that, but this data is likely going to be going to other people who will be simply taking the device, popping an SD card in, getting data, and pulling the SD card out. If I make them mess around with binary, I feel like it's just going to wind up not getting used. I could process the data for them, but then they'll be forced to come to me every time in which I think the same outcome would follow.

@Antonio51 Antonio, that was a great addition to the program. I am now only printing to the file once instead of multiple times each cycle. Thanks!

Logical ... for a caracter you open the file, write, then close. All operations that takes "some" time ! I had to resolve that problem in saving parameters of Temp, humidity and some others things (100 caracters) every 5 seconds, so I know ...

@Antonio51 Ideally, I'd like to squeeze at least 260Hz out of these write operations, as that's the speed of my MPU-6050s recording ability. I'm measuring some really high accelerations that are dampened quickly, so I really want to maximize my readings/second

Don't add datas that you really don't use ... as labels ... You know what and how you are saving your data, save only these, eventually as binary datas in place of strings of caracters. You can also use a "data set" record. A little more complicated but usefull.

@Antonio51 I also noticed I was using a lot of strings unnecessarily. Unfortunately I need both decimal places as well as positive/negatives, so I'm guessing floats are the only way to have all that, even though the acceleration values will never exceed 64 m/S^2

If I remember well, I could read 8 kbytes /second and writing quasi similar but did not measure this because every 5 seconds. (on an Arduino 16 MHz). I thing it would be beter on a LGT328 (?) which is running at 32 MHz.

@Antonio51 A faster microcontroller is probably what I need, but I'm certain this has to be possible. I'm merely logging XYZ values and time. I guess now I've got some personal attachment to trying to solve this. I'm also a beginner so it's a good learning opportunity for me.

If datas are 2 bytes large enough (15 bits + sign), you can save all as word ... but when reading out, change or correct the type of variables accordingly. Good luck !

So I spent a while longer banging my head on the wall, and I finally found a solution to my issue. @DaveNewton provided several links that lead to other links, and I found my way to here 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, and this MPU-6050 based accelerometer.
// 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.


text:
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_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();
  }
}

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

Sorry I should have clarified a bit more than what is in the code, I am using pins 11 and 13 for SPI, ignoring the setup defined early in the code. There are two declaration statements for the display - one uses any combination of pins for the display and the other uses 11 and 13 plus the other three.
As for the pullup resistors, no I haven't put those in. However I did think that if the sensor worked when its own example code was run (even without the resistors) that it should run in conjunction with the display. Or is there some interference I am missing?


text:
Bluetooth module with lowest latency to communicate with PC
I am making a haptic feedback glove using Arduino and HC-05 bluetooth module to communicate with PC.
There are rotary encoders on the finger which send value to PC through Arduino mega. The PC returns the force to be excerted on the finger back to Arduino which then controls the motor. The communication between Arduino and PC is established through an HC-05 module wired to Arduino and connected to PC wirelessly over bluetooth. Through COM-Port of Arduino-IDE, serial communication is established.
When the program runs, the PC (Unity) sends the force to Arduino but there is a huge latency in the order of tens of milliseconds. After Unity calculates the force, Arduino receives this force after at least 30ms (I have not measured the accurate value). In order to make sure the delay is a result of bluetooth communication, I connected the Arduino to PC using USB and the latency was reduced. This points to the fact that the delay is caused by the bluetooth.
I did some research into that and found that there is something called BLE as opposed to classic bluetooth which decreases the delay. According to this link, HC-05 which uses classic bluetooth has a latency of 100ms and BLE has a latency of 6ms.
I want to buy a bluetooth module that has BLE capability like HM-10. Before that, I wanted to know if I have understood the information correctly: i.e buying an HM-10 would decrease communication gap. Is there any alternatives to bluetooth communication (such as ethernet or wifi) which would provide low or lower latency?


text:
AccelStepper library - motor ticks when turning
When I'm using the AccelStepper library to control this closed loop stepper motor, the motor ticks when turning, maybe ~5 ticks/sec. Depending on the speed of the motor the ticks become more (at higher speed) or less (at lower speed) powerful.
At a low speed (<500 steps/sec) the ticks can only be detected by holding the motor and feeling the ticks. However, at greater speeds (>1000) you can also hear them and see the motor "house" move a little bit with each tick.
I'm not 100% certain but it seems like the ticking frequency is the same independent of speed. So if I tell the motor to make 3 revolutions, a slower speed will result in more ticks total because more time is needed to complete the revolutions.
Neither using the stepper library that comes with the Arduino IDE nor manually setting the pulse pin HIGH and LOW in a loop results in any ticking. Therefore I don't think it is the motor that is faulty.
This is the code I'm using:
#include <AccelStepper.h>

AccelStepper stepper(1, 7, 6);

long receivedPosition = 0;
long receivedSpeed = 0;
char receivedCommand;
bool newData, runAllowed = false;

void setup()
{
    Serial.begin(9600); //define baud rate
}

void loop()
{
    checkSerial();

    moveStepper();
}

void moveStepper()
{
    if (runAllowed == true)
    {
        if (stepper.currentPosition() != receivedPosition)
        {
            stepper.runSpeedToPosition();
        }
        else
        {
            runAllowed = false;
        }
    }
}

void checkSerial()
{
    if (Serial.available() > 0)
    {
        receivedCommand = Serial.read();
        newData = true;
    }

    if (newData == true)
    {
        // RUN
        if (receivedCommand == 'r')
        {
            runAllowed = true;

            receivedPosition = Serial.parseFloat(); //value for the steps
            receivedSpeed = Serial.parseFloat(); //value for the speed

            stepper.moveTo(receivedPosition);
            stepper.setMaxSpeed(receivedSpeed);
            stepper.setSpeed(receivedSpeed);

        }
    }
    newData = false;
}

Everything seems to work fine except for the ticking issue. Does anyone have any idea why this happens?

Does this also happen when you use one of the example sketches of the AccelStepper library?


text:
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:

And here is my code:

Please see why we shouldn't post images of text. We don't know much about your motor or how the motor is interfaced to the Arduino.

I might not drive the motor directly off the Arduino like that; even a wee motor can draw more current than the Arduino can handle.

Disconnect that circuit immediately - you are damaging your Arduino

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.

Thanks for the answer, but I would like to regulate motor speed manually not by changing PWM value in the program.

Then you need a motor driver that will take an analogue input. You can't just slap a potentiometer in there and hope it'll work.

Thanks, I'll try it. Fortunately I've got L293d.

@Macios216 "Regulating it manually" and "changing PWM values" are separate issues--the means of determining the PWM value is arbitrary. Take the pot value and map it to the PWM value.

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?

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.
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


text:
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 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 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?

If you connect SDA and SCL to the same resistor, you're shorting them together. Does not sound like a good idea.

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.

Thanks very much for your answer. I also had a feeling that connecting both pins together via the resistor was not a good idea, but the post I had mentioned made it sound plausible. Also the datasheet didn't give any indication of what kind of resistors to use or how to calculate their value and what info I found was between 4.7K and 10K. I tried with 10K each and it worked. However, there will also be a barometric sensor module (BMP180) attached which has its own internal resistors. Would this then mean I wouldn't need resistors for the DS1337 in the first place?

@jhorv The resistors only need to exist. It doesn't matter if they are in another module or wired direct to the bus. You can even have multiple resistors, in which case the resistance is just the parallel total of those resistances.

I made a mistake with the resistors. I forgot to pull the interrupt pin high, thus it was always low and that made it look like the DS1337 was waking the MCU. The DS1337 is not working with 10K resistors but neither with 1K resistors. I keep getting an I2C error 4. I will start a new question after doing some more tests and background research. Thanks again for your help.


text:
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?

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

Did you set it up to use it? https://support.arduino.cc/hc/en-us/articles/360014779679-Why-doesn-t-the-5V-pin-work-in-the-Arduino-Nano-33-BLE-boards-

I haven't made a solder bridge on the two pads, however I am powering the board through the USB port (please note that this is not the BLE Sense board)

Oh I have just seen that as an OR when it is actually and AND, so both conditions need to be met

Says there it needs to be bridged. Also stated on https://www.arduino.cc/en/Guide/NANO33BLE.

To be honest, I couldn't find any information on my google search, but you are right, it says so.

I am new to this, and I am not sure how to bridge that as I don't have any soldering thingy

FWIW I searched for "Arduino Nano ble 33 5v pin" and it was the top two hits.

You are completely right I don't know what I was thinking of, the answer was on my first two results too, I think I read OR rather than AND and wrongly assumed my board was faulty, or something like that, sorry about that

No worries--it's only obvious after it's obvious ;)

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


text:
ESP32 + Attiny85 AC Dimmer
I am working on an AC Dimmer project using ESP32 and Attiny85.

Note : I know ATtiny85 is overkill for this project, And it can be done without Attiny85, I have already done this using ESP32 alone. But I have some PCB laying around designed in such a manner. So thought of doing this.

Here ESP32 communicates to Attiny over i2c.
ESP - Master
Attiny - Slave

Here Zero Cross Detector(ZCD) circuit is connected to PB1. and T1 to Triac Circuit
Depending on the commands over i2c from ESP to each Attiny, It controls the brightness.
The Problem
I am able to set the brightness using i2c (like LOW, MED, HIGH, OFF). But only once.
For example, if I set it to HIGH state initially it will get stuck in that state, Even if any other command is given, Similar for all others. Basically, it will only work once.
I think the interrupt is causing the problem, once interrupt is attached the i2c isn't responding
Here are codes
Slave https://pastebin.com/sqsMYLa0
#include "PinChangeInterrupt.h"
#include "TinyWireS.h"

#define I2C_SLAVE_ADDR  2
int AC_LOAD = 3;
int ZCD_Pin = 1;
int dimming = 128;
int Speed[3] = {90, 50, 20};
int speedValue;
bool fan;

void setup() {
  pinMode(AC_LOAD, OUTPUT);
  TinyWireS.begin(I2C_SLAVE_ADDR);
  TinyWireS.onReceive(receiveEvent);
  pinMode(ZCD_Pin, INPUT_PULLUP);
}

void zero_crosss_int()  //function to be fired at the zero crossing to dim the light
{
  int dimtime = (75 * dimming);  // For 60Hz =>65
  delayMicroseconds(dimtime);    // Wait till firing the TRIAC
  digitalWrite(AC_LOAD, HIGH);   // Fire the TRIAC
  delayMicroseconds(100);         // triac On propogation delay  // (for 60Hz use 8.33) Some Triacs need a longer period
  digitalWrite(AC_LOAD, LOW);    // No longer trigger the TRIAC (the next zero crossing will swith it off) TRIAC
}

void receiveEvent(uint8_t howMany)
{
  byte byteRcvd = 0;
  if (TinyWireS.available()) {
    byteRcvd = TinyWireS.receive();     // get the byte from master

    if (byteRcvd == '0') {
      fan = false;
      detachPinChangeInterrupt(digitalPinToPCINT(ZCD_Pin));
      digitalWrite(AC_LOAD, LOW);
    }
    if (byteRcvd == '1') {
      fan = true;
      speedValue = Speed[0];
      attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
    }
    if (byteRcvd == '2') {
      fan = true;
      speedValue = Speed[1];
      attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
    }
    if (byteRcvd == '3') {
      fan = true;
      speedValue = Speed[2];
      attachPCINT(digitalPinToPCINT(ZCD_Pin), zero_crosss_int, RISING);
    }
    dimming = speedValue;
  }
}

void loop() {
  delay(100);
}

Master https://pastebin.com/E5U74LEx
#include <Wire.h>
//#define I2C_SLAVE_1_ADDR  1
#define I2C_SLAVE_2_ADDR  2

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
  Serial.begin(9600);
  Serial.print("Ready");
}

char x = 0;

void loop() {
  if (Serial.available() > 0) {

    x = Serial.read();

    if (x == '0') {
      Wire.beginTransmission(2);
      Wire.write('0');
      Wire.endTransmission();
      Serial.print("Send 0");
    }
    if (x == '1') {
      Wire.beginTransmission(2);
      Wire.write('1');
      Wire.endTransmission();
      Serial.print("Send 1");
    }
    if (x == '2') {
      Wire.beginTransmission(2);
      Wire.write('2');
      Wire.endTransmission();
      Serial.print("Send 2");
    }
    if (x == '3') {
      Wire.beginTransmission(2);
      Wire.write('3');
      Wire.endTransmission();
      Serial.print("Send 3");
    }
  }
}

For testing, I have used Serial monitor for sending commands. Later It will be done using MQTT

That's a pretty long delay in the ISR; have you tried setting a state and handling the rest in loop?

@DaveNewton Yes, but the output is flickering.
here is the code https://pastebin.com/FnTkE8hZ

https://arduino.stackexchange.com/questions/63631/fan-regulator-control-from-arduino/63674#63674


text:
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.

They're different things: one is a specific interface to Arduino Firmata, one is a generic serial port library. "Superior" depends on context, usage, etc. Either would work perfectly fine, each would require a different approach.

Thank you so much

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

Did you see Dave Newton's comment below the question?

no but thanks i needed it


text:
MQ-4 Sensor working fine with Beetle Bluno BLE but not with Arduino Nano 33 BLE
I have an MQ-4 sensor connected to a Beetle Bluno BLE that seems to work fine, however, when I change the board to an Arduino Nano 33 BLE, the sensor doesn't seem to work well (I get an arbitrary oscillation in values coming from the sensor but these don't increase or decrease with the presence of gas).
Beetle Bluno BLE setup:

MQ-4:GND -> Beetle:GND
MQ-4:VCC -> Beetle:5v
MQ-4:AO -> Beetle:A1

Arduino Nano 33 BLE setup:

MQ-4:GND -> Arduino:GND
MQ-4:VCC -> Arduino:3.3v
MQ-4:AO -> Arduino:A1

(image slightly missleading because VCD is actually not connected to 5V but to 3.3V)
The only difference is the 5v instead of 3.3v, however, I also tried powering the sensor externally with 5v and it makes no difference.

A schematic might be helpful, particularly for the Arduino, along with "not working well" actually means.

Description updated with a schematic and a definition

You fixed the 5V jumper and verified it's putting out 5V?

No, I am not using the 5v but the 3.3v pin instead

AFAIK that sensor requires 5V according to sources like the SparkFun.

I see, well I tried powering the sensor with 5v externally with the same results

Which is why a schematic would be helpful to see if there's a missing shared ground or something.

I really don't know how to make schematics, but what I've done is connect the VCC and GND of the MQ-4 sensor to my other Beetle Bluno board to pins V5 and GND, and pin A0 stayed in Arduino Nano

I think the ground connection would also need to be hooked up to the Arduino if I'm understanding what you're saying.

After adding the ground to the Arduino, it seems like it is reading the values from the sensor, however, the values are "micro-oscillating" up and down in a way that doesn't happen in the Beetle Bluno

There are any number of reasons that could be happening; wiring and power supplies are often the first places to look when dealing with analog signals. (Which is not what I usually do, so I'm probably useless :)

Try hand drawing the schematic. There are a lot of videos on line that will explain it to you. Frizzing is not considered a schematic it leaves to many things unconnected. A hint when the supplier says 5V they do not expect it to work with much less or more, that is a very important parameter. Also it is a big help when you post links to the technical information on the hardware items. The next most important thing is current, can your power supply supply enough current. The Arduino a Power Supply it is NOT! Violating this rule can cause a lot of problems especially with analog hardware.


text:
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); } }

Is updateFader() being called when it is supposed to be called? updateFader() is only called when faderPos == lastfaderPosition. This is unlikely to be the case because there will be noise (electrical due to quantisisation and vibration) on int faderPos = analogRead(mainFaderPin). Try something like if (abs(faderPos - lastfaderPosition) < some_threshold)...)

Yea, that seems to work pretty well. I added coupling/decoupling capacitors to the MIDI In/Out circuit, and that fixed the noise right up. It's actually very stable now

What happens if position is less than faderMin e.g. incomingVelocity is zero? Or if position is greater than  faderMax, e.g. incomingVelocity is 1016 (or 127 * 8) when faderMax is about 1023 - 40 = 983?

Hi Tim, when the motor is within the tolerance for error, it simply stops moving. Without this tolerance for error, the motor will move erratically back and forth, trying to find the exact value to position itself in. Give it a tolerance, and it works right out. This is a necessary step for motorized faders

The second version in your updated question works by fluke.

But the first version doesn't work at all, lol. I'm lost

I'm working on a explanation, but have to go now. I'll post later.

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 by the MIDI Association.
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.
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:
// 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:
// 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():
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.
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.
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:

Control Surface
Arduino MIDI Library

These already implement the MIDI message parsing using callbacks, e.g.:

Using callbacks
Using callbacks .ino

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().
#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);
    }
}