body:
I'm using an Arduino Nano with a capacitive touch sensor and a potentiometer. I'm trying to get my code to differentiate between three different program states.

- One is when my touch sensor is NOT being touched.
- Two is when my touch sensor IS being touched.
- And three is when my touch sensor is being touched AND a potentiometer is being moved at the same time.

I'm having trouble picking up the second program state, when I'm simply touching the fader but not moving the potentiometer. Program state 1 works great, but program state 3 activates even when there's no data coming in from the potentioeter.

Here's the code. And ideas?

```
#include <CapacitiveSensor.h>
#define rxPin 4
#define txPin 1

const byte touchSend = 2;
const byte touchReceive = 7;

byte minimumCp = 200; // Raise if the fader is too sensitive (0-16383)

bool touched = false; //Is the fader currently being touched?

CapacitiveSensor touchSensor = CapacitiveSensor(touchReceive, touchSend);

void setup() {
  touchSensor.set_CS_AutocaL_Millis(0xFFFFFFFF);
  pinMode(rxPin, INPUT );
  pinMode(txPin, OUTPUT);
  Serial.begin(57600);
}
void loop() {
  int faderPos = analogRead(A7);
  int lastfaderValue;
  int totalCp =  touchSensor.capacitiveSensor(30);
  if (totalCp <= minimumCp) {  // Not Touching Fader
      touched = false;
      Serial.println("Not Touching Fader");
      delay(15);}
  if ((faderPos == lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader
      touched = true;
      Serial.println("Touching Fader, NOT Moving");
      delay(15);}
  if ((faderPos != lastfaderValue) && (totalCp > minimumCp)) { // Touching Fader and Moving
      touched = true;
      Serial.println("Touching Fader, Moving");
      delay(15);}
  lastfaderValue = faderPos; }
```

title: Touch Sensor and Potentiometer - Need some help

Answers: 1

body:
Figured it out.

I had the lastfaderValue integer in the wrong spot. It works when I put it at the beginning of the code (before the setup).

I also added a tolerance, so that the potentiometer can still fluctuate slightly when I'm not touching it.

Works well now.


body:
I've got a DC motor connected to an Arduino Nano, L298N H-Bridge and a 12v Power supply. I'm trying to make it respond to incoming MIDI data a bit quicker. Right now, it seems awfully slow, and lags in response to quick value changes. I'm using MIDI to send data into my Arduino, so my baud rate is limited to 31250.

The issue is mainly with my DAW (Ableton), as my motor responds quickly when I try to control it with a fader on my MIDI keyboard.

Note: I'm also using a potentiometer and a capacitive touch sensor in this code. I'll try to simplify it as much as I can so I can isolate the issue
Here's the code:

```cpp
#include <SoftwareSerial.h> // MIDI Input
#include <CapacitiveSensor.h>
#include <MIDI.h> // MIDI Output
#define txPin 1
#define rxPin 4

SoftwareSerial midiSerial (rxPin, txPin);

const byte touchSend    = 2;//Send pin for Capacitance Sensing Circuit (Digital 7)
const byte motorPWM     = 3;
const byte motorDown    = 5;
const byte motorUp      = 6;
const byte touchReceive = 7; //Receive pin for Capacitance Sensing Circuit (Digital 8)
const byte wiper        = 7; //Position of fader relative to GND (Analog 0)

int incomingCommand;
int incomingNote;
int incomingVelocity;
byte motorSpeed = 75; // 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 = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
bool touched = false; //Is the fader currently being touched?
long lastDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay    = 10;    // the debounce time; increase if the output flickers
int lastfaderValue    = 0;

byte ch1Vol = 224;
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(MIDI_CHANNEL_OMNI);
  while (!Serial);
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  pinMode(rxPin, INPUT );
  pinMode(txPin, OUTPUT);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader(); }

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

void loop() {
  int faderPos = analogRead(wiper);
  int faderMIDI = faderPos / 8;
  int faderHiResMIDI = ((faderPos *16) - 8191);
  while ( midiSerial.available() > 0 ) {
    int commandByte = midiSerial.read();
    int noteByte = midiSerial.read();
    byte velocityByte = midiSerial.read();
    midiSerial.write( commandByte);
    midiSerial.write( noteByte);
    midiSerial.write( velocityByte);
    incomingCommand = commandByte;
    incomingNote = noteByte;
    incomingVelocity = velocityByte*8; }

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

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 && !touched) {
    digitalWrite(motorDown, HIGH);
    while (position < analogRead(wiper) - tolerance && !touched) {}; //Loops until motor is done moving
    digitalWrite(motorDown, LOW); }
  else if (position > analogRead(wiper) + tolerance && position < faderMax && !touched) {
    digitalWrite(motorUp, HIGH);
    while (position > analogRead(wiper) + tolerance && !touched) {}; //Loops until motor is done moving
    digitalWrite(motorUp, LOW); } }
```

title: Motor response is lagging

Answers: 0


body:
This is my code -

    // Basic demo for accelerometer readings from Adafruit MPU6050

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

    Adafruit_MPU6050 mpu;

    void setup(void) {
      Serial.begin(115200);
      while (!Serial)
        delay(10); // will pause Zero, Leonardo, etc until serial console opens

      Serial.println("Adafruit MPU6050 test!");

      // 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);
      Serial.print("Accelerometer range set to: ");
      switch (mpu.getAccelerometerRange()) {
      case MPU6050_RANGE_2_G:
        Serial.println("+-2G");
        break;
      case MPU6050_RANGE_4_G:
        Serial.println("+-4G");
        break;
      case MPU6050_RANGE_8_G:
        Serial.println("+-8G");
        break;
      case MPU6050_RANGE_16_G:
        Serial.println("+-16G");
        break;
      }
      mpu.setGyroRange(MPU6050_RANGE_500_DEG);
      Serial.print("Gyro range set to: ");
      switch (mpu.getGyroRange()) {
      case MPU6050_RANGE_250_DEG:
        Serial.println("+- 250 deg/s");
        break;
      case MPU6050_RANGE_500_DEG:
        Serial.println("+- 500 deg/s");
        break;
      case MPU6050_RANGE_1000_DEG:
        Serial.println("+- 1000 deg/s");
        break;
      case MPU6050_RANGE_2000_DEG:
        Serial.println("+- 2000 deg/s");
        break;
      }

      mpu.setFilterBandwidth(MPU6050_BAND_21_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;
      }

      Serial.println("");
      delay(100);
    }

    void loop() {

      /* Get new sensor events with the readings */
      sensors_event_t a, g, temp;
      mpu.getEvent(&a, &g, &temp);

      /* Print out the values */
      Serial.print("Acceleration X: ");
      Serial.print(a.acceleration.x);
      Serial.print(", Y: ");
      Serial.print(a.acceleration.y);
      Serial.print(", Z: ");
      Serial.print(a.acceleration.z);
      Serial.println(" m/s^2");

      Serial.print("Rotation X: ");
      Serial.print(g.gyro.x);
      Serial.print(", Y: ");
      Serial.print(g.gyro.y);
      Serial.print(", Z: ");
      Serial.print(g.gyro.z);
      Serial.println(" rad/s");

      Serial.print("Temperature: ");
      Serial.print(temp.temperature);
      Serial.println(" degC");

      Serial.println("");
      delay(500);
    }

and this is my error-

    Adafruit MPU6050 test!
    Failed to find MPU6050 chip
    Adafruit MPU6050 test!
    Failed to find MPU6050 chip

wires are connected properly

title: Arduino MPU error

Answers: 0


body:
I am building a project that requires the SAMD21 microcontroller to send a `resetToFactory` signal to the NINA W102 on Arduino Nano 33 IoT. My plan is that, once the W102 receives the signal will do NVS formatting and restart itself, and then I need the SAMD21 to restart afterward by an event triggering from the W102(W102 needs to finish the restart cycle first), see the figure.
[![enter image description here][1]][1]

The communication protocol is SPI as the WIFININA lib does.

I have few attempts by trying to read the GPIO voltage from W102, however, it doesn't work because SPI on SAMD21 side will just hang until the W102 finished the restart even though I remove the `waitForSlaveReady()` for receiving the reply, so I can't get any event triggering.

By the way, I can't simply use the `RESET_N` because the program won't know to do the NVS formatting first.

Does anyone have related experience or ideas? Thank you very much.

Best regards,

Edwin Lu

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

title: How can the SAMD21 chip knows when the on-board NINA W102 restarts

Answers: 1

body:
I have solved this later I post the question.

The solution is using the fact which SPI on the SAMD21 will hang while W102 restarts, so I just set the SAMD21 restart immediately after the program continues.

Best regards,

Edwin Lu


body:
Trying to power the 12V relay from an Arduino to make an automatic cocktail maker.  Looking to power 12V water pumps off of the relay.  However, the relay is not clicking, only getting the light.

The connections FROM the Arduino TO the relay is as follows:

| Arduino | Relay |
|---------|-------|
| 5V      | VCC   |
| GND     | GND   |
| pin 3   | IN1   |

Also pictures of circuit are provided. The Arduino is powered by USB laptop.

![Relay][1]
![Arduino][2]
[![Test code][4]][4]

  [1]: https://i.stack.imgur.com/T427q.jpg
  [2]: https://i.stack.imgur.com/AsFTj.jpg
  [3]: https://i.stack.imgur.com/GZ5Eg.jpg
  [4]: https://i.stack.imgur.com/7oxIN.jpg

title: 12V Relay not clicking

Answers: 1

body:
After search the internet,
i believe the 12v relay need 12v to click.

You may check these :

https://handtoolsforfun.com/how-to-connect-a-12v-relay-board-to-arduino/

https://www.instructables.com/Connecting-a-12V-Relay-to-Arduino/


body:
I tried searching codes for MCP2515 with Arduino,
On Arduino Forums, Instructables, Electronics Hub, YouTube etc.

All of them were codes for a transmitter node and a receiver node.
Sensors on one node and result on the other end.

Can we connect two Arduinos using MCP2515 and communicate TWO WAY?

title: Can MCP2515 CANBUS Controller be used for two way communication?

Answers: 2

body:
I never used CAN bus myself, but what you could do is one of the following:

- Letting the transmitter send a specific (short) message to the receiver. In case the receiver has something to transmit, it sends a specific reply back, so the transmitter can request the receiver to send the actual message to be sent. The disadvantage is that polling is needed.
- If you want the receiver to be able to send its message as fast as possible, add a separate wire next to the CAN bus communication. If that line is LOW or HIGH (decide yourself), then the transmitter can 'immediately' send a message to have the receiver send its actual message.

body:
---Yes---
It should work nicely. They operate only in simplex mode (sending or receiving) to the outside world. Internally they also monitor what they are sending for error checking etc. From the user point they would appear to be bidirectional because they can switch between send and receive messages rapidly, message by message. Of course the bus speed helps. You can get upto 1 Meg with these. I use Cory Fowler's "mcp_can.h". You can get it at: "https://github.com/coryjfowler/MCP_CAN_lib". The library has both send and receive .ino files, get them to work first.  Since CAN is priority Based NDA Non Destructive Arbitration the higher priority message will prevail regardless of who else is on the bus or is sending a message.

Do not forget to put jumpers on the module to terminate the bus. Note the bus gets terminated only at the physical ends. The bus design impedance is 60 Ohm, the termination resistors are 120 ohms.

You simply combine the send and receive sections of code in your module, nothing special to do. You initialize both send and receive at the same time with basically the same information.  You will find the information for this in the setup() section of the code. Be sure to check crystal frequencies, I have seen both 8 and 16 Mhz crystals on these boards.

Per the Bosch specification, which is readily available,  The CAN bus does arbitration automatically by a defined priority on a bit by bit basis. To send a message with the MPC2515 you load it and when the bus becomes available it will transmit it, if there is an error it will retry many times (internal counter) and if it fails you will know. When a message is sent it must receive an ACK in a specified part of the can frame. This can be generated by any node. Your internal protocol needs to determine if the right node got the message.
By the time your external logic can determine it wants to send a message and send a signal it will have already been sent in a standard CAN setup. Any number of modules can start transmitting but the arbitration will weed them out and the highest priority message will get through. Every node will receive every message, depending on its filtering etc it may accept it or ignore it. You can pole or take an interrupt any time it receives a message etc.


body:
I'm trying to control a heating element with PWM with an [Arduino Nano][1], 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).

[![Enter image description here][2]][2]

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

  [1]: https://en.wikipedia.org/wiki/List_of_Arduino_boards_and_compatible_systems#Official
  [2]: https://i.stack.imgur.com/i5YCj.png

title: Can’t set duty cycle to 0% with custom PWM

Answers: 2

body:
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][core]: 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:

```c++
TCCR1A &= ~_BV(COM1A1);  // disable PWM on pin OC1A = PB1
PORTB  &= _BV(PB1);      // set PB1 to LOW
```

[core]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/cores/arduino/wiring_analog.c#L112-L115

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


body:
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);

}

title: How to set 16x2 LCD I2C display backlight?

Answers: 1

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


body:
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 :)

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

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

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

title: Deepsleep ESP8266 Thing

Answers: 0


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

title: Custom LED toggling function: one out of three LEDs misbehave

Answers: 1

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


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

title: Help to set vertical dcroll on SSD1306

Answers: 1

body:
This line achieved it for me. I stole it from here: [Adafruit Forum][1]

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

  [1]: https://forums.adafruit.com/viewtopic.php?f=47&t=133759


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

title: How do I read from a correct data address of LIDAR using Arduino in I2C?

Answers: 1

body:
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
    }


body:
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 are the 2 sms-s which overheats.][1]][1]

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

title: My Arduino UNO works, but 2 smd overheats. Why?

Answers: 1

body:
These look like C2 and C3 in the [Arduino UNO R3 schematic][1]. 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.

  [1]: https://www.arduino.cc/en/uploads/Main/Arduino_Uno_Rev3-schematic.pdf


body:
So i'm new to arduino and i'm working on a project that will require 3 modules/sensors.
I wanted to know, can all of the following modules work with the arduino mega 2560 that comes with [this][1]
touch display?

The other modules (apart from the touch display) would be:
- [Fingerprint scanner][2]
- [9g servo][3]

If its not possible, please tell me what hardware I would need to run all these sensors together. Thanks :D.

  [1]: https://www.aliexpress.com/item/32756200704.html?spm=a2g0o.detail.1000013.12.711673f1ncqoRr&gps-id=pcDetailBottomMoreThisSeller&scm=1007.13339.169870.0&scm_id=1007.13339.169870.0&scm-url=1007.13339.169870.0&pvid=f8448ca9-d64e-4e65-ab67-9449f3d31926&_t=gps-id:pcDetailBottomMoreThisSeller,scm-url:1007.13339.169870.0,pvid:f8448ca9-d64e-4e65-ab67-9449f3d31926,tpp_buckets:668#0#131923#0_668#0#131923#0_668#888#3325#18_668#888#3325#18_668#2846#8111#1996_668#5811#27175#21_668#2717#7558#144_668#1000022185#1000066058#0_668#3468#15612#337_668#2846#8111#1996_668#5811#27175#21_668#2717#7558#144_668#3164#9976#596_668#3468#15612#337
  [2]: https://he.aliexpress.com/item/1005001692576941.html?spm=a2g0o.detail.1000060.2.1d0f7d47W6D9VB&gps-id=pcDetailBottomMoreThisSeller&scm=1007.13339.169870.0&scm_id=1007.13339.169870.0&scm-url=1007.13339.169870.0&pvid=e6840541-0a73-4a77-af30-11823a618765&_t=gps-id:pcDetailBottomMoreThisSeller,scm-url:1007.13339.169870.0,pvid:e6840541-0a73-4a77-af30-11823a618765,tpp_buckets:668#0#131923#0_668#0#131923#0_668#888#3325#18_668#888#3325#18_668#2846#8111#1996_668#5811#27175#21_668#2717#7558#144_668#1000022185#1000066058#0_668#3468#15612#365_668#2846#8111#1996_668#5811#27175#21_668#2717#7558#144_668#3164#9976#596_668#3468#15612#365
  [3]: https://www.aliexpress.com/item/1005002056653701.html?spm=a2g0o.productlist.0.0.5cb93734JK6wGL&algo_pvid=aebdfac6-36b8-4f2d-9b74-4a6fad059f04&algo_exp_id=aebdfac6-36b8-4f2d-9b74-4a6fad059f04-3

title: Can I support all these sensors? Will I have enough pins?

Answers: 0


body:
I'm using this piece of code to try to poll an IMU sensor at 100 Hz (for a AHRS sensor fusion library).

    void loop(void)
    {
      // nonblocking code variables
      static uint32_t last_ms;
      uint32_t ms;
      // delay between samples
      ms = millis();
      if (ms - last_ms < 10) return;
      last_ms = ms;

      sensor_data (); //...

My 1st question is should I be declaring `last_ms` as a global variable instead of static?

Also, should this code be at the beginning or end of loop? My understanding is we are basically checking how long the previous loop took. And if it took less than 10 ms (100 Hz) we do nothing. But doesn't that mean that we might still get deviation from 100 Hz due to the time it takes to complete loop (about 2-5ms in my case), so effectively it's 10 ms + loop complete time?

Sorry if this is a stupid question.

title: How to write nonblocking code, for polling sensor at 100 Hz

Answers: 2

body:
The time range your sensor code will be executed is 10ms to 10ms + the execution time of the first part of the loop (until the return) and the execution time outside of `loop()`. These additional times don't always apply, but in the worst case you can have up to that additional delay (because it means you are checking the `millis()` value only so often).

The mentioned additional delay is rather short (microseconds realm). Your sensor code is only executed, when the time is reached. As long as you don't disable interrupts, the Timer0 interrupt will continue to count further for `millis()`, so its value will increase independently from the execution time of your sensor code.

That is as long as the sensor code also doesn't take longer than 10ms (or a bit less, accounting for some overhead). As your sensor code only takes up to 5ms (according to your question), you should be safe here.

If `millis()` is accurate enough for you I cannot say. Thats up to your exact requirements. For more accurate timing an own timer interrupt would be better, though that also limits you with what you can do. Inside an interrupt you cannot execute code, that relies on interrupts (like communication over Serial or I2C). Depending on your sensors using your above code is already enough and should work good.

> should I be declaring last_ms as a global variable instead of static?

There is no definitive answer to that, but generally it is good to limit the scope of variables to the minimum needed (to avoid possible conflicts). `last_ms` is not needed anywhere else, so creating it locally and static is a good way to do it. Memory wise it doesn't really make a difference.

body:
> should I be declaring `last_ms` as a global variable instead of
> static?

Local static is better, as it limits the scope of the variable to just
where it is needed. Consider making it global only if the code is part
of a tutorial meant for beginners which may be confused by the keyword
`static`.

> should this code be at the beginning or end of loop?

The conditional early return only makes sense if `loop()` has nothing
more to do once the sensor data is handled, thus this should go at the
very end of `loop()`. However, if `loop()` does more than just handle
this data, I think it would be cleaner to avoid the early return: either
put this in a separate function (which can return early), or condition
the handling of the sensor on `ms - last_ms >= 10`.

> My understanding is we are basically checking how long the previous
> loop took.

No. The test is looking at how much time has elapsed since the previous
time `last_ms` was updated, which could be many `loop()` iterations ago.

> But doesn't that mean that we might still get deviation from 100 Hz
> due to the time it takes to complete loop (about 2-5ms in my case), so
> effectively it's 10 ms + loop complete time?

Indeed. With this logic, 10 ms is the _minimum_ time between calls
to `sensor_data()`. If you want to ensure an accurate _average_ polling
time, you should update `last_ms` by adding 10. You will still have
sole jitter though.

A small note about `millis()`: since the value is updated every
1.024 ms, it occasionally has to jump by two units at once, and has
therefore 1 ms of jitter. For a period as short as 10 ms, I
would rather use `micros()`. For example:

```c++
const uint32_t POLLING_PERIOD = 10000;  // 1e4 us = 10 ms

// Call this from loop()
void handle_sensor()
{
    static uint32_t last_us;
    if (micros() - last_us < POLLING_PERIOD) return;
    last_us += POLLING_PERIOD;
    sensor_data();
    // ...
}
```

**Edit**: About why `last_us` has to be incremented by a constant
amount, consider this alternative:

```c++
void handle_sensor()
{
    static uint32_t last_us;
    uint32_t now = micros()
    if (now - last_us < POLLING_PERIOD) return;
    last_us = now;
    sensor_data();
    // ...
}
```

The code following the `if ... return;` line will be executed when the
tested condition is false, i.e. when `now - last_us >= POLLING_PERIOD`.
It may happen that we sometimes have strict equality (`now - last_us ==
POLLING_PERIOD`) but, since any code execution takes time, sometimes
`now - last_us` will be strictly larger than `POLLING_PERIOD`. Every
time this happens `last_us` will be incremented by _more_ than
`POLLING_PERIOD`. This means that the small timing errors accumulate.

If, instead, `last_us` is updated by adding a constant amount, we still
have timing errors (because of the time needed to execute any code), but
they are not cumulative. In other words, we have jitter, but the
_average_ polling frequency is right.


body:
Can I program my ESP32 to send a string MQTT data while also blinking the InBuilt LED?

If yes, then how to do so

Thanks in advance

title: ESP32 send data while blinking LED

Answers: 1

body:
The ESP32 have two core, each core can do diferents tasks. Then, you can send data with one core and blink the LED with another core.

To do this, you need to use a multicore programming. I recommend to use the `FreeRTOS` (ESP32 support this). [See more](https://www.freertos.org/).

Look the example "Let's multitask: Blink with Hello" [here](https://exploreembedded.com/wiki/Hello_World_with_ESP32_Explained), is that what  you want.

Read the [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/system/freertos.html) about the `FreeRTOS` in ESP32.

Example in Arduino IDE:
```
#include <Arduino_FreeRTOS.h>

// define two tasks for Blink & AnalogRead
void TaskBlink( void *pvParameters );
void TaskAnalogRead( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {

  // Now set up two tasks to run independently.
  xTaskCreate(
    TaskBlink
    ,  (const portCHAR *)"Blink"   // A name just for humans
    ,  128  // Stack size
    ,  NULL
    ,  2  // priority
    ,  NULL );

  xTaskCreate(
    TaskAnalogRead
    ,  (const portCHAR *) "AnalogRead"
    ,  128 // This stack size can be checked & adjusted by reading Highwater
    ,  NULL
    ,  1  // priority
    ,  NULL );

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
}

void loop()
{
  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskBlink(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  // initialize digital pin 13 as an output.
  pinMode(13, OUTPUT);

  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
    digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
    vTaskDelay( 1000 / portTICK_PERIOD_MS ); // wait for one second
  }
}

void TaskAnalogRead(void *pvParameters)  // This is a task.
{
  (void) pvParameters;
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);

  for (;;)
  {
    // read the input on analog pin 0:
    int sensorValue = analogRead(A0);
    // print out the value you read:
    Serial.println(sensorValue);
    vTaskDelay(1);  // one tick delay (15ms) in between reads for stability
  }
}
```
[Reference](https://create.arduino.cc/projecthub/feilipu/using-freertos-multi-tasking-in-arduino-ebc3cc).


body:
I'm successfully sending a GET request (in the setup function, to load certificates,) but my POST request fails with a bunch of AT errors. I suspect this has to do with the way I'm formatting the POST. Any ideas would be appreciated.

Code follows:

    // MKRGSM - Version: 1.5.0
    #include <MKRGSM.h>
    #include <ArduinoJson.h>
    #include <Arduino_MKRGPS.h>

    const char PINNUMBER[]     = "";
    // APN data

    const char GPRS_APN[]      = SECRET_GPRS_APN;

    const char GPRS_LOGIN[]    = "";

    const char GPRS_PASSWORD[] = "";

    DynamicJsonDocument doc(1024);

    // initialize the library instance

    GSMSSLClient client;

    GPRS gprs;

    GSM gsmAccess(true);

    // Specify IP address or hostname

    char server[] = "webhook.site";
    char path[] = "/ce480c43-95a8-4f1e-b996-bc02f6d1adaa";
    int port = 443;

    void setup() {

      // initialize serial communications and wait for port to open:

      Serial.begin(9600);

      while (!Serial) {

        ; // wait for serial port to connect. Needed for native USB port only

      }

      // If you are using the MKR GPS as shield, change the next line to pass

      // the GPS_MODE_SHIELD parameter to the GPS.begin(...)
      delay(200);

      if (!GPS.begin()) {

        Serial.println("Failed to initialize GPS!");

        while (1);

      }
      Serial.println("Starting Arduino GSM ping.");
      // connection state
      bool connected = false;

      // After starting the modem with GSM.begin()
      // attach the shield to the GPRS network with the APN, login and password
      while (!connected)
      {
        if ((gsmAccess.begin(PINNUMBER) == GSM_READY) &&
            (gprs.attachGPRS(GPRS_APN, GPRS_LOGIN, GPRS_PASSWORD) == GPRS_READY))
        {
          connected = true;
        }
        else
        {
          Serial.println("Not connected");
          delay(1000);
        }
      }

      Serial.println("connecting...");

      // if you get a connection, report back via serial:
      // Use this to load Root Certs the first time
      if (client.connect(server, port))
      // Use this to not load Root Certs anymore as done last time and stored in modem's flash
    //  if (client.connect(server, port, false))
      {
            Serial.println("connected");

        // Make a HTTP request:

        client.print("GET ");

        client.print(path);

        client.println(" HTTP/1.1");

        client.print("Host: ");

        client.println(server);

        client.println("Connection: close");

        client.println();
      }
      else
      {
        // if you didn't get a connection to the server:
        Serial.println("connection failed");
      }
    }

    void loop() {

      ...GPS stuff happens here

      // print GPS values

      Serial.println();

      Serial.print("Location: ");

      Serial.print(latitude, 7);

      Serial.print(", ");

      Serial.println(longitude, 7);

      Serial.print("Altitude: ");

      Serial.print(altitude);

      Serial.println("m");

      Serial.print("Number of satellites: ");

      Serial.println(satellites);

      doc["latitude"] = latitude;
      doc["longitude"] = longitude;
      doc["altitude"] = altitude;

      String location;
      serializeJson(doc, location);
      Serial.print("Location string: ");
      Serial.println(location);

      Serial.println();

      Serial.println("Starting Arduino web client.");

      // connection state

      if (client.available()) {
        Serial.println("Sending location");
        client.print("POST ");
        client.print(path);
        client.println(" HTTP/1.1");
        delay(5);
        client.println("Content-Type: application/json;");
        delay(5);
        client.print("Content-Length: ");
        client.println(location.length());
        client.print("Host: ");
        client.println(server);
        delay(5);
        client.println("Connection: close");
        delay(5);
        client.println();
        delay(5);
        client.println(location);
        Serial.print("Successfully sent location");

        if (!client.available() && !client.connected()) {

          Serial.println();

          Serial.println("disconnecting.");

          client.stop();
        }
      } else {
        // if you didn't get a connection to the server:
        Serial.println("connection failed");
      }

    }

Here's what the output looks like:

> Location: 32.1208382, 35.2468376 Altitude: 640.40m Number of
> satellites: 5 Location string:
> {"latitude":32.12084,"longitude":35.24684,"altitude":640.4}
>
> Starting Arduino web client. Sending location
> AT+USOWR=0,13,"504F53542068747470733A2F2F"
>
> ERROR
> AT+USOWR=0,37,"2F63653438306334332D393561382D346631652D623939362D626330326636643161646161"
>
> ERROR AT+USOWR=0,9,"20485454502F312E31"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR
> AT+USOWR=0,31,"436F6E74656E742D547970653A206170706C69636174696F6E2F6A736F6E3B"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,16,"436F6E74656E742D4C656E6774683A20"
>
> ERROR AT+USOWR=0,2,"3539"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,6,"486F73743A20"
>
> ERROR AT+USOWR=0,12,"776562686F6F6B2E73697465"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,17,"436F6E6E656374696F6E3A20636C6F7365"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR
> AT+USOWR=0,59,"7B226C61746974756465223A33322E31323038342C226C6F6E676974756465223A33352E32343638342C22616C746974756465223A3634302E347D"
>
> ERROR AT+USOWR=0,2,"0D0A"
>
> ERROR

I could send the data as parameters in the GET query, but that's ugly.

title: MKR1400-how do I troubleshoot a POST request?

Answers: 2

body:
Your HTTP request is badly formatted.  You have:

```
POST https://webhook.site/ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Content-Type: application/json
```

Instead the protocol is implied by the port you are connecting to, and the domain name does *not* go in the path on the server component - it has its own header.

Your request should look more like:

```
POST /ce480c43-95a8-4f1e-b996-bc02f6d1adaa HTTP/1.1
Host: webhook.site
Content-Type: application/json
Content-Length: [x]
Connection: close

[location]
```

Where `[x]` is `location.length()` and `[location]` is the content of the `location` string.

body: The problem was that ```GSM gsmAccess;``` needed to be ```GSM gsmAccess(true)```. Unfortunately, while that solves the immediate problem, which is that the client was not initializing, there are other issues which deserve a separate question.


body:
I'm not sure why this has been so difficult for me, but I'm trying to control the acceleration of a 10v DC motor with an Arduino UNO and an L298n H-Bridge. Using a 12v regulated power supply to power the motor

For the life of me, I can't get a smooth acceleration/deceleration for this. I want the motor to move back and forth with a potentiometer, slowing down as it reaches the '0' and '10' positions. This works, but it's not very smooth

```
const byte motorUp      = 4;
const byte motorDown    = 5;
const byte motorPWM     = 6;

const int speed1 = 85;
const int speed2 = 92;
const int speed3 = 100;
const int speed4 = 110;
const int speed5 = 130;
const int speed6 = 190;

int state = 0;

const byte wiper        = A0; //Position of fader relative to GND (Analog 0)
double faderMax = 0; //Value read by fader's maximum position (0-1023)
double faderMin = 0; //Value read by fader's minimum position (0-1023)
byte motorSpeed = 255;  // Raise if the fader is too slow (0-255)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)

void setup() {
  Serial.begin(250000);
  pinMode(motorDown, OUTPUT);
  pinMode(motorUp, OUTPUT);
  pinMode(motorPWM, OUTPUT);
  analogWrite(motorPWM, motorSpeed);
  calibrateFader(); }

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

void loop () {
  moveMotorUp();}

void moveMotorUp() {
  while (analogRead(A0) <= 100) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
   while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW); }
  while (analogRead(A0) > 1000) {
    analogWrite (motorPWM, speed1);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW);
    moveMotorDown(); } }

void moveMotorDown() {

  while (analogRead(A0) > 1000) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 900) && (analogRead(A0) <= 1000)) {
    analogWrite (motorPWM, speed2);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 800) && (analogRead(A0) <= 900)) {
    analogWrite (motorPWM, speed3);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 700) && (analogRead(A0) <= 800)) {
    analogWrite (motorPWM, speed4);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 600) && (analogRead(A0) <= 700)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 500) && (analogRead(A0) <= 600)) {
    analogWrite (motorPWM, speed6);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 400) && (analogRead(A0) <= 500)) {
    analogWrite (motorPWM, speed5);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 300) && (analogRead(A0) <= 400)) {
    analogWrite (motorPWM, speed4);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 200) && (analogRead(A0) <= 300)) {
    analogWrite (motorPWM, speed3);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 100) && (analogRead(A0) <= 200)) {
    analogWrite (motorPWM, speed2);
    digitalWrite (motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while ((analogRead(A0) > 10) && (analogRead(A0) <= 100)) {
    analogWrite(motorPWM, speed1);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW); }
  while (analogRead(A0) <= 10) {
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW);
    moveMotorUp(); } }
```

I hope it's simpler than this - Any ideas?
Thanks

title: DC Motor Acceleration with PWM

Answers: 1

body:
I think you need to think a little differently. Instead of "Move it at this speed until you get to here" you need to think more along the lines of "Where am I? Where do I want to get to? How far away is it?"

Basically the further you have to go the faster you want to go. The closer you get to your target value the slower you want to go.

Simply put - you want to convert the distance between your current and target positions into a proportional speed.

Take one variable: the target value that you want to get to. Take one reading: the current location of the fader. Subtract one from the other.

Take the sign of the result - that defines what direction you want the motor to turn in.  Take the "absolute" (`abs(...)`) value of the result - that is the distance you are away from your target.  Divide that absolute value by a speed factor to keep it within the range of your PWM, or lower if you want to go slower. Set the speed of the motor to that result.

So if you want to get to 0 and you are currently reading 1000 from the fader then:

* Difference = 0 - 1000 = -1000
* Sign is negative, so set direction to "down".
* Distance is `abs(-1000)`, or 1000.
* Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 250
* Set speed to 250

Then a moment later you may be reading 738 from the ADC - so this time:

* Difference = 0 - 738 = -738
* Sign is negative, so set direction to "down".
* Distance is `abs(-738)`, or 738.
* Divide by 4 (max ADC is 1023, max PWM is 255 - 1023/4 = 255) = 184
* Set speed to 184

Keep doing that until you get to your target value (or within a certain tolerance of it) at which point you stop and wait for a new target value to be selected (or automatically change the target value as per your sweep demo - if 0 then set to 1023. If 1023 then set to 0).

This method then allows you to go directly to any value you choose with a deceleration as it approaches that target.


body:
My project is to transfer an image wirelessly via BLE from my Sparkfun EDGE board using the Arduino IDE to another laptop. In the following, for simplicity, I have reduced the program to transmit integers via BLE. This already works but it takes a long time (~0.5 seconds) to transfer a few bytes. However, from the BLE specifications, much more should be possible.
This is the stripped down code for the Board using Arduino:
```

#include <ArduinoBLE.h>
#include "utility/HCI.h"    // needed for sendcommand
#include <string>

const char BLE_PERIPHERAL_NAME[] = "Peripheral Hello World BLE";
BLEService Test("83436682-10c6-4dad-acb1-133927f3f080");
BLEStringCharacteristic HelloWorlds("83436682-10c6-4dad-acb1-133927f3f080", BLERead | BLENotify, 512);

#define SERIAL_PORT Serial
#define BAUD_RATE   115200 //(originally, 460800)

void setup() {

  // Start up serial monitor
  SERIAL_PORT.begin(BAUD_RATE);

#ifdef BLE_Debug
  BLE.debug(SERIAL_PORT);         // enable display HCI commands
#endif
  BLE.setLocalName(BLE_PERIPHERAL_NAME);
  BLE.begin();

  BLE.setAdvertisedService(Test);

  Test.addCharacteristic(HelloWorlds);

  BLE.addService(Test);
  BLE.advertise();
//BLE part end
  }

void loop(){
    int period=3000; //minimum time [ms] to be spent in each loop. This is to give the BLE enought time to transmit. To be adjusted depending on the test.
    unsigned long timing=millis();

    BLE.poll();

    int v1;
    v1 = rand() % 100;

    //Generate 8 integer to be transmitted
    String sixteen=String(v1);
    for (uint32_t ccc=0; ccc < 8; ccc=ccc+1){

      v1 = rand() % 100;
      sixteen = sixteen + " " +String(v1);
    }
  HelloWorlds.writeValue(sixteen);
  SERIAL_PORT.print(sixteen);
  SERIAL_PORT.print("   ");

   while(millis() < timing + period){
   }

  }
```
The code compiles, runs on the EDGE board and I receive the random bytes on my phone (NRF app) as well as on the other laptop.
On the other laptop, I use gatttool in the Ubuntu terminal to receive the packets:
```
gatttool -I
connect C0:4B:39:C9:B1:04
char-read-hnd c
```
(I obtain the handle "c" through inspecting the characteristics before).
Then, I do receive the String, but it takes the some hundreds of milliseconds until the integers are displayed. I also automated this in a Python script using *pexpect* and then print the timestamps after the *sendline* and *expect* command and it shows the time difference of ~hundreds of milliseconds.

The data rate that I target should be at least hundreds of bytes per second.

Thank you kind community.

title: Send/Stream BLE (Bluetooth Low Energy) data with high data rate with Arduino

Answers: 0


body:
I have a very simple PCB that uses 3 GPIO on a ATtiny85 to control 6 LEDs using charlieplexing.

When I try to program certain patterns of lit LEDs (pseudo PWM) I get some LEDs lighting dimly when they should be fully off.

Example where only top or bottom three LEDs should be on alternately:

[![Video][1]][1]

You can see that LEDs 2 and 5 are dimly glowing rather than being fully off.

I do not have problems when lighting the LEDs one at a time in sequence.

I do not have problems lighting odd and even LEDs alternately.

The schematic is:

[![schematic][2]][2]

The buttons are used to change up and down through 6 modes of operation. Mode 0 lights the LEDs one at a time in sequence. Mode 1 alternates the odd and even LEDs. Mode 2 lights upper or lower three LEDs alternately (and has ghosting problem), the other modes just steadily illuminate the corresponding LED.

The code is split into several files:

main.ino:

~~~
Button leftButton = Button(3);
Button rightButton = Button(4);
Sequencer sequencer = Sequencer(200); // ms per step
Alternator alternator = Alternator(0b00101010, 0b00010101);

void setup() {
  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);
  pinMode(2, OUTPUT);
}

// ------------------------------------------------------------------

const int maxMode = 5;
int mode = 0;

void loop() {
  if (leftButton.wasPressed())  {
    if (++mode > maxMode) { mode = 0; }
    initMode(mode);
  }
  if (rightButton.wasPressed()) {
    if (--mode < 0) { mode = maxMode; }
    initMode(mode);
  }

  switch(mode) {
    case (0): sequencer.check(); break;
    case (1):
    case (2): alternator.check(); break;
    default: lightLED(mode); break;
  }
}

// ------------------------------------------------------------------

void initMode(int mode) {
  switch (mode) {
    case (0): sequencer.reset(); break;
    case (1): alternator = Alternator(0b00101010, 0b00010101); break;
    case (2): alternator = Alternator(0b00111000, 0b00000111); break;
  }
}
~~~

Alternator.ino

~~~
class Alternator {

  private:
    unsigned long whenChanged = 0;
    int interval = 500; // ms
    byte pattern, pattern1, pattern2; // bitmap
    int count = 0;

  public:
  Alternator(byte pattern1, byte pattern2) {
    this->pattern1 = pattern1;
    this->pattern2 = pattern2;
  }

  void check() {

    if ((millis() - whenChanged) > interval) {
      if (pattern == pattern1) { pattern = pattern2; }
      else                     { pattern = pattern1; }
      whenChanged = millis();
    }

    if (++count > 5) { count = 0; }
    if (((pattern >> count) & 1) == 1) {
      lightLED(count);
    }

  }

};
~~~

Sequence.ino

~~~
class Sequencer {

  private:
    int seq;                            // LED# 0-5
    unsigned long whenLastStep;         // ms
    int stepTime;                       // ms
    const int aDay = 24 * 3600 * 1000;  // ms

  public:
    Sequencer(int stepTime) {
      if (stepTime < 1) { stepTime = 1; }
      if (stepTime > aDay) { stepTime = aDay; }
      this->stepTime = stepTime;
      this->seq = 0;
      this->whenLastStep = 0;
    }

    void check() {
      if ((millis() - whenLastStep) > stepTime) {
        lightLED(seq++);
        if (seq > 5) { seq = 0; }
        whenLastStep = millis();
      }
    }

    void reset() {
      this->seq = 0;
    }
};
~~~

Charlieplex.ino

~~~
const int highs[6] = {0,1,2,1,2,0};  // GPIOs for LEDs 0-5
const int lows[6]  = {1,0,1,2,0,2};

// Manipulates 3 GPIO outputs to light one of 6 LEDs.
void lightLED(int i) {
  int h, l;     // pin to set high, low
  if (i < 0 || i >= 6) {
    h = 99; l = 99;  // all LEDS off
  } else {
    h = highs[i];
    l = lows[i];
  }

  for (int j=0; j<=2; j++) {
    if (j==h || j==l) {
      pinMode(j, OUTPUT);
      if (j==h) {
        digitalWrite(h, HIGH);
      } else {
        digitalWrite(l, LOW);
      }
    } else {
      pinMode(j, INPUT); // tri-state
    }
  }
}
~~~

Buttons.ino

~~~
class Button {

  private:
    int pin;
    const int DebounceDelay = 100;      // milliseconds
    int lastState = HIGH;               // Previous status of button
    unsigned long whenLastPressed = 0;  // Last time button was pressed

  public:
    Button(int pin) {
      this->pin = pin;
      pinMode(pin, INPUT_PULLUP);
    }

    // Was there an up (HIGH) to down (LOW) transition since last call, and still held down?
    bool wasPressed() {
      bool result = false;
      if ((millis() - whenLastPressed) > DebounceDelay) {
        int state = digitalRead(pin);
        if ((state == LOW) && (lastState == HIGH)) {
          result = true;
          whenLastPressed = millis();
        }
        lastState = state;
      }
      return result;
    }

};
~~~

I'm not sure where I am going wrong, any ideas?

  [1]: https://i.stack.imgur.com/L7PRm.gif
  [2]: https://i.stack.imgur.com/pNYSG.png

title: Unwanted ghosting with charlieplexed LEDs

Answers: 2

body:
Charlieplexing code doesn't reset the state of unused pin and if the port value is HIGH + mode INPUT, it means the pull-up is enabled.

Solution is reset all pins to LOW before code starts changing directions. And the last step would be setting correct pin to HIGH.

If you want to do it in single loop, you might observe really short pulses (it might or might not be visible - at the higher frequencies it'll be more obvious)

It could be also much faster than using digitalWrite and pinMode, something like:

<!-- language: c++ -->

      void charlieplex(uint8_t i) {
        constexpr uint8_t clrpins = ~(_BV(PB0) | _BV(PB1) | _BV(PB2));
        constexpr uint8_t dirs[]  = { 0b011, 0b011, 0b110, 0b110, 0b101, 0b101};
        constexpr uint8_t outs[]  = { 0b001, 0b010, 0b010, 0b100, 0b001, 0b100};

        PORTB &= clrpins; // clear output pins
        DDRB  &= clrpins; // clear direction pins (0 == input, 1 == output)
        if (i < 6) {  // such easy condition if you use:  uint8_t i
          DDRB  |= dirs[i]; // And set the correct pins as outputs
          PORTB |= outs[i]; // And set the correct pin as high
        }
      }

It's not tested, but it should be pretty much it

body:
A secondary issue is that using `millis()` to update the timestamps will cause the interval to cumulatively drag.

To keep the interval constant, update:
 - `whenChanged` with `interval`
 - `whenLastStep` with `stepTime`.

**Alternator.ino**

```cpp
void check() {

  if ((millis() - whenChanged) > interval) {
    if (pattern == pattern1) { pattern = pattern2; }
    else                     { pattern = pattern1; }
    whenChanged += interval;  // Constant interval.
  }

  if (++count > 5) { count = 0; }
  if (((pattern >> count) & 1) == 1) {
    lightLED(count);
  }

}
```

**Sequence.ino**

```cpp
void check() {
  if ((millis() - whenLastStep) > stepTime) {
    lightLED(seq++);
    if (seq > 5) { seq = 0; }
    whenLastStep += stepTime;  // Constant time step.
  }
}
```

This subtle difference is explained very well by @edgar-bonet in his answer about [polling a sensor at 100 Hz][1].

Also, `Button::wasPressed()` is prone to a negative blip occurring at the time of sampling the input pin, i.e. the blip will be interpreted as a continuous press of `DebounceDelay` (100 ms). Compare with this [simple debouncer][2] I put on GitHub.

  [1]: https://arduino.stackexchange.com/a/84823/68310
  [2]: https://github.com/TimMathias/Arduino-Debouncer


body:
I'm working on a project that uses an Arduino UNO and a motorized fader to send and receive MIDI data from my computer/musical keyboard. I'm trying to set up my motor with PID to control the position and speed of the motor - Been having some difficulty, but after watching a few tutorials I think I'm starting to grasp the idea.

Here's the code that I came up with so far - I'm not sure if this is correct for PID control or not, but it makes my motor respond very strangely to any positioning data that is coming in.

```cpp
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 1

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;

double faderMax = 0;
double faderMin = 0;

byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte tolerance  = 10;  // Raise if the fader is too shaky (0-1023)

int incomingCommand;
int incomingNote;
int incomingVelocity;

int currentPosition;
unsigned targetPosition;
unsigned long distanceToTarget;
unsigned PIDspeed;

void setup() {
  midiSerial.begin(31250);
  Serial.begin(250000);
  analogWrite(motorPWM, motorSpeed);
  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() {

  while ( midiSerial.available() > 0) {
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
    midiSerial.write( incomingCommand);
    midiSerial.write( incomingNote);
    midiSerial.write( incomingVelocity);
    targetPosition = incomingVelocity*8.05511811024;
    currentPosition = analogRead(A0);
    distanceToTarget = targetPosition-currentPosition;
  }
  PIDspeed = abs(distanceToTarget)/6;

  if (distanceToTarget >=0) {
    analogWrite(motorPWM, PIDspeed);
    digitalWrite(motorUp, HIGH);
    digitalWrite(motorDown, LOW);
  }

  if (distanceToTarget <=0) {
    analogWrite(motorPWM, PIDspeed);
    digitalWrite(motorDown, HIGH);
    digitalWrite(motorUp, LOW);
  }
}
```

Updated code:
```cpp
#include <SoftwareSerial.h>
#define rxPin 2
#define txPin 1

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;

double faderMax = 1023;
double faderMin = 0;

byte motorSpeed = 150;  // Raise if the fader is too slow (0-255)
byte tolerance = 10;  // Raise if the fader is too shaky (0-1023)
byte Proportional = 12;

unsigned int incomingCommand;
unsigned int incomingNote;
unsigned int incomingVelocity;

unsigned int PIDspeed;
int currentPosition;
int targetPosition;
int distanceToTarget;

void setup()
{
    midiSerial.begin(31250);
    Serial.begin(250000);
    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()
{
    while (midiSerial.available() >= 3)
    {
        incomingCommand = midiSerial.read();
        incomingNote = midiSerial.read();
        incomingVelocity = midiSerial.read();
        if (targetPosition <= 1023)
        {
            midiSerial.write(incomingCommand);
            midiSerial.write(incomingNote);
            midiSerial.write(incomingVelocity);
        }
        targetPosition = incomingVelocity * 8.05511811024;
    }
    currentPosition = analogRead(A0);
    distanceToTarget = (targetPosition - currentPosition);
    PIDspeed = (abs(distanceToTarget) / Proportional) + 90;
    analogWrite(motorPWM, PIDspeed);
    if (targetPosition <= 1023)
    {
        if (distanceToTarget > 60)
        {
            digitalWrite(motorUp, HIGH);
        }
        if (distanceToTarget < 60)
        {
            digitalWrite(motorDown, HIGH);
        }
        if ((distanceToTarget >= -60) && (distanceToTarget <= 60))
        {
            digitalWrite(motorDown, LOW);
            digitalWrite(motorUp, LOW);
        }
    }
}
```

In this version, the motor is actually less responsive than before. I think it must have to do with the data that's coming in from my DAW, which isn't consistently a piece of command, note or velocity data. For example, if I select a different track in my DAW, it sends data into my Arduino. When I read anything greater than 0 bytes, the data still comes in, but the note, command and velocity readings are more sporadically located. It was suggested by another that I try using a MIDI parser, but that's a different topic I suppose.

title: Assistance with PID DC Motor Acceleration

Answers: 2

body:
I see 2 main problems with your code, that would make it behave strangely:

- You are calculating the new motor speed and decide about the direction based on the variable `distanceToTarget`. But this variable is only updated, when there is data coming from your MIDI interface. I guess thats only happening, when you want to change the target position. But the motor control runs on **every** loop iteration, which will be way more often, than you can get the MIDI data. To solve this please move the lines

        currentPosition = analogRead(A0);
        distanceToTarget = targetPosition-currentPosition;

    out of the `while(midiSerial.available() > 0)` loop. Just put then right after it.

- At the start of your midi code you check for more than zero bytes being available from `midiSerial`, but then you are reading 3 bytes in total, without knowing, if there are actually 3 bytes to read. `SoftwareSerial.read()` will not wait for a byte to come in, it will just return -1. So it can very well be that, just one byte is already received, when the midi code is executed. The rest will be received later. So the rest of the variables is just garbage/invalid. Also this means that sender and receiver are now misaligned. The other 2 bytes (which are received later) will then be handled by the midi code next time as if they were byte 1 and 2 (not 2 and 3). So the next transitions will also be garbage/invalid, until it aligns itself again by chance.

    To solve this you should check for at least 3 bytes being available (since you want to read 3 bytes):

        while ( midiSerial.available() >= 3 ) {

---

Note: As of your comments you seem to have a misunderstanding, what PID and PWM actually is.

- PWM is just a way to drive the motor with variable speed by turning the pin on and off very fast, with different ratios between on and off time. With a high ratio towards on time the motor will turn faster than with a low ratio towards on time. This ratio translates to the range from 0 to 255 on an Arduino. So you need PWM to drive a motor with variable speed on the Arduino. You cannot cut that out.

- PID is a closed feedback loop control. It denotes a way to calculate a new output value (PWM motor value) based on the measured input value (measured current position). PID stands for Proportional Integral Differential, so for the different terms in the calculations. With PID first the deviation between measured input and target/setpoint is calculated then the PID function is evaluated (with its proportional, integral and differential part of the deviation). With that you get the output value, that you can feed to your output device (the motor here).

    PID has nothing to do with PWM. They are totally different things. Only when driving an electromechanical device you might need PWM in the same system as PID. PWM is the hardware way of driving the motor, PID is the way to calculate the output value in a closed feedback loop to reach the target position smoothly and fast.

Actually with your current code (when corrected as described above) already does the proportional part of PID (since you calculate the new speed from the distance to target, so the deviation from the target position). To get full PID you would also need to implement the rest. I would suggest using the [Arduino PID library][1], which already handles the calculation for you. You just need to call it correctly (refer to the examples of the library).

  [1]: https://github.com/br3ttb/Arduino-PID-Library/

body:
There is a fundamental problem with the way you are reading the serial data. Read this excellent article by @Majenko:
https://majenko.co.uk/blog/reading-serial-arduino

The following code will read the last 3 bytes. If, for example, there are 9 bytes available, it will ignore the first 6 bytes:

```cpp
while (midiSerial.available() >= 3)
{
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
. . .
}
```

This will read the next 3 bytes:

```cpp
if (midiSerial.available() >= 3)
{
    incomingCommand = midiSerial.read();
    incomingNote = midiSerial.read();
    incomingVelocity = midiSerial.read();
. . .
}
```

Here is the tweaked `loop()` which:
 - uses `if (midiSerial.available() >= 3)` to read the next 3 bytes.
 - clips the `targetPosition` if it's out of bounds (0 to 1023).
 - clips the `PIDspeed` if it's out of range (0 to 255).
 - switches the other motor control signal off before enabling the current one just in case the `targetPosition` crossed zones between `loop()` iterations.

```cpp
const int QUIESCENT_BOUNDARY = 60;
const float INCOMING_VELOCITY_SCALE = 1023.0 / 255.0;

byte incomingCommand;
byte incomingNote;
byte incomingVelocity;

void loop()
{
    if (midiSerial.available() >= 3)                // Use `if` to get the next 3 bytes available.
    {
        incomingCommand = midiSerial.read();
        incomingNote = midiSerial.read();
        incomingVelocity = midiSerial.read();
        midiSerial.write(incomingCommand);
        midiSerial.write(incomingNote);
        midiSerial.write(incomingVelocity);
        targetPosition = incomingVelocity * INCOMING_VELOCITY_SCALE;
        if (targetPosition > 1023)                  // Clip if out of bounds.
        {
            targetPosition = 1023;
        }
    }
    currentPosition = analogRead(A0);
    distanceToTarget = targetPosition - currentPosition;
    PIDspeed = abs(distanceToTarget) / 6;           // TODO: Tune the PID equation.
    if (PIDspeed > 255)                             // Clip if out of range.
    {
        PIDspeed = 255;
    }
    analogWrite(motorPWM, PIDspeed);
    if (distanceToTarget > QUIESCENT_BOUNDARY)      // Above the positive bound of the quiescent zone.
    {
        digitalWrite(motorDown, LOW);               // Switch the down control off before switching the up control on.
        digitalWrite(motorUp, HIGH);
    }
    else if (distanceToTarget < -QUIESCENT_BOUNDARY)// Below the negative bound of the quiescent zone.
    {
        digitalWrite(motorUp, LOW);                 // Switch the up control off before switching the down control on.
        digitalWrite(motorDown, HIGH);
    }
    else                                            // In the quiescent zone.
    {
        digitalWrite(motorDown, LOW);
        digitalWrite(motorUp, LOW);
    }
}
```

That should help you to tune the PID equation.


body:
**Solved** : In Mac I went back to Tools --> Boards Manager, then removed 3.0 and downgraded to 2.5 and it started working. I found the solution in [this][2] thread.

--------------

The current connection between uno R3 and esp8266 is

  **UNO** ----- **ESP8266**

    RX — RX
    TX — TX
    GND — GND
    3.3V — VCC (used bread board)
    3.3V — CH_PD (used bread board)
    GPIO - GND

   **UNO** ----- **UNO**

    Reset -- GND

Then ESP8266 send "OK" when I send AT from the serial monitor. When uploading the red light and blue blinks in esp8266 and rx and tx light blinks at uno r3.

I had to do `sudo launchctl stop /dev/cu.usbmodemxxx` before running below command.

Since I have GPIO connected to GND, I though that would trigger the programming mode, but for some reason it gives `Invalid head of packet`. I get same error when trying to upload code from arduino IDE.

I tried below command too from cmd line.

    $sudo python esptool.py -t --chip esp8266  --port /dev/cu.usbmodemxxx --before no_reset flash_id
    esptool.py v2.8
    Serial port /dev/cu.usbmodemxxx
    Connecting...TRACE +0.000 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        5555555555555555 5555555555c0     | UUUUUUUUUUUUU.
    TRACE +0.000 Read 3 bytes: f8fef0
    TRACE +0.000 Read invalid data: f8fef0
    TRACE +0.000 Remaining data in serial buffer:
    .TRACE +0.056 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        5555555555555555 5555555555c0     | UUUUUUUUUUUUU.
    TRACE +0.001 Read 1 bytes: f0
    TRACE +0.000 Read invalid data: f0
    TRACE +0.000 Remaining data in serial buffer: f0f0
    .TRACE +0.056 command op=0x08 data len=36 wait_response=1 timeout=0.100 data=
        0707122055555555 5555555555555555 | ... UUUUUUUUUUUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU
        55555555                          | UUUU
    TRACE +0.000 Write 46 bytes:
        c000082400000000 0007071220555555 | ...$........ UUU
        5555555555555555 5555555555555555 | UUUUUUUUUUUUUUUU

    ......

    A fatal error occurred: Failed to connect to ESP8266: Invalid head of packet (0xF0)

Below is the image of the arduino IDE with code and board selected as esp8266.

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

I am following this post https://iot-guider.com/esp8266-nodemcu/how-to-program-esp8266-with-arduino-uno/ and I have exact same hardwares.

**UPDATE:**

When I tried this connection in Windows it starts uploading code without error. So, my guess is its something to do with MAC.

  [1]: https://i.stack.imgur.com/k7Zc8.png
  [2]: https://forum.arduino.cc/t/esp-8266-timed-out-waiting-for-packet-header/597634/18

title: Why am I getting Invalid head of packet (0xF0) error when trying to upload code to esp8266?

Answers: 1

body:
The tutorial you linked to can not be trusted! There are mayor mistakes:

 1. They connect a 3.3V device with a 5V devices without taking any measures to convert the logic levels.
 2. Connecting Rx to Rx (or Tx to Tx) is typically not what you do if you want to communicate between devices. A transmitting line must be connected to a receiving line for that. In case the arduino is `Serial.print()`ing something himself, a bus contention can cause a short circuit and harm the UART pins.
 3. They are plugging the ESP into a breadboard which simply doesn't work! This will short several pins and possibly kill some hardware. At least it can't work like that.

I don't know if the person who did this tutorial just has no idea or is trolling, but you need to find a different tutorial (and - I'm sorry to say - possibly get a new ESP).

If all you want is to use the arduino as a USB to UART bridge, I suggest to remove the atmega chip from its socket on the arduino or make sure that it doesn't run a sketch were it prints something. The UART pins should also be configured as inputs.


body:
guys.
I am workin on a project. I have two channel for Serial RS232 communication. Main and Stand-By channel. If Main channel has some problem and, cannot communicate for 15 seconds then I want to start Stand-By channel communication. How can I do that? I want to listen to channel's RX with Arduino. I think I can use MAX 232 for Serial to TTL convert. Can I listen to channel's RX with Arduino then Can I decide which channel should work?

Thank you,guys..

title: Serial communication detect

Answers: 0


body:
I'm looking to get arduino 1.0.x to work on my Mint/Guix hybrid box in order to hack around with 3D printer firmware. Unfortunately I can't get the stock `void setup () {} void loop () {}` to compile. I get the following compilation error:
```
  This report would have more information with
  "Show verbose output during compilation"
  enabled in File > Preferences.
Arduino: 1.0.6 (Linux), Board: "Arduino Mega 2560 or Mega ADK"
In file included from /home/blueberry/.guix-profile/include/c++/stdlib.h:36,
                 from /home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/cores/arduino/Arduino.h:23,
                 from sketch_jun23a.ino:3:
/home/blueberry/.guix-profile/include/c++/cstdlib:57: error: expected initializer before ‘_GLIBCXX_NORETURN’
/home/blueberry/.guix-profile/include/c++/cstdlib:59: error: expected initializer before ‘_GLIBCXX_NORETURN’
In file included from /home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/cores/arduino/Arduino.h:23,
                 from sketch_jun23a.ino:3:
/home/blueberry/.guix-profile/include/c++/stdlib.h:38: error: ‘std::abort’ has not been declared
/home/blueberry/.guix-profile/include/c++/stdlib.h:40: error: ‘std::exit’ has not been declared
In file included from /home/blueberry/.guix-profile/include/c++/cmath:42,
                 from /home/blueberry/.guix-profile/include/c++/math.h:36,
                 from /home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/cores/arduino/Arduino.h:25,
                 from sketch_jun23a.ino:3:
/home/blueberry/.guix-profile/include/c++/bits/cpp_type_traits.h:69: error: expected `{' before ‘_GLIBCXX_VISIBILITY’
/home/blueberry/.guix-profile/include/c++/bits/cpp_type_traits.h:69: error: expected constructor, destructor, or type conversion before ‘(’ token
In file included from /home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/cores/arduino/Arduino.h:235,
                 from sketch_jun23a.ino:3:
/home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/variants/mega/pins_arduino.h:59: error: expected `}' at end of input
/home/blueberry/Software/arduino-old/arduino-1.0.6/hardware/arduino/variants/mega/pins_arduino.h:59: error: expected `}' at end of input
```
Guix clobbers the Arduino IDE include paths, even when my Nix environment is run. I can't get `snapd` to run on my box, setting up a custom Guix environment does not fix the problem, flathub doesn't have arduino 1.0.x available. Where can I go from here? Thanks.

title: Getting Arduino 1.0.x to run on Guix: error: expected initializer before ‘_GLIBCXX_NORETURN’, error: ‘std::abort’ has not been declared, etc

Answers: 0


body:
I have an Arduino Zero processor (atsamd21g18a) with a microSD shield connected (check images of schematics)[![micro][1]][1]

[![sd][2]][2]

  [2]: https://i.stack.imgur.com/Bh3XA.jpg
  [1]: https://i.stack.imgur.com/2VWRZ.jpg

The point is that I cant make it to work, not with `sd.h` sketch and not with `sdfat.h` sketch.

Chip-select for the SD card is A3 or digital pin 17.

## sd.h sketch

```c++
#include <SPI.h>
#include <SD.h>

File myFile;

void setup() {
  // Open serial communications and wait for port to open:
  SerialUSB.begin(9600);
  delay(1000);

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

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

  if (!SD.begin(A3)) {
    SerialUSB.println("initialization failed!");
    return;
  }
  SerialUSB.println("initialization done.");

  if (SD.exists("example.txt")) {
    SerialUSB.println("example.txt exists.");
  } else {
    SerialUSB.println("example.txt doesn't exist.");
  }

  // open a new file and immediately close it:
  SerialUSB.println("Creating example.txt...");
  myFile = SD.open("example.txt", FILE_WRITE);
  myFile.close();

  // Check to see if the file exists:
  if (SD.exists("example.txt")) {
    SerialUSB.println("example.txt exists.");
  } else {
    SerialUSB.println("example.txt doesn't exist.");
  }

  // delete the file:
  SerialUSB.println("Removing example.txt...");
  //SD.remove("example.txt");

  if (SD.exists("example.txt")) {
    SerialUSB.println("example.txt exists.");
  } else {
    SerialUSB.println("example.txt doesn't exist.");
  }
}

void loop() {
  // nothing happens after setup finishes.
}
```

## sdfat.h code

```c++
const int chipSelect = A3;
/*
 SD card read/write

 This example shows how to read and write data to and from an SD card file
 The circuit:
 * SD card attached to SPI bus as follows:
 ** MOSI - pin 11
 ** MISO - pin 12
 ** CLK - pin 13
 ** CS - pin 4

 created   Nov 2010
 by David A. Mellis
 updated 2 Dec 2010
 by Tom Igoe
 modified by Bill Greiman 11 Apr 2011
 This example code is in the public domain.

 */
#include <SdFat.h>
SdFat sd;
SdFile myFile;

pinMode(chipSelect, OUTPUT);

void setup() {
  delay(5000);
  SerialUSB.begin(9600);
  SerialUSB.println("Serial start");
  //while (!SerialUSB) {}  // wait for Leonardo
  //SerialUSB.println("Type any character to start");
  //while (SerialUSB.read() <= 0) {}
  delay(1000);  // catch Due reset problem

  // Initialize SdFat or print a detailed error message and halt
  // Use half speed like the native library.
  // change to SPI_FULL_SPEED for more performance.
  if (!sd.begin(chipSelect, SPI_HALF_SPEED)) sd.initErrorHalt();

  // open the file for write at end like the Native SD library
  if (!myFile.open("test.txt", O_RDWR | O_CREAT | O_AT_END)) {
    sd.errorHalt("opening test.txt for write failed");
  }
  // if the file opened okay, write to it:
  SerialUSB.print("Writing to test.txt...");
  myFile.println("testing 1, 2, 3.");

  // close the file:
  myFile.close();
  SerialUSB.println("done.");

  // re-open the file for reading:
  if (!myFile.open("test.txt", O_READ)) {
    sd.errorHalt("opening test.txt for read failed");
  }
  SerialUSB.println("test.txt:");

  // read from the file until there's nothing else in it:
  int data;
  while ((data = myFile.read()) >= 0) SerialUSB.write(data);
  // close the file:
  myFile.close();
}

void loop() {
  // nothing happens after setup
  SerialUSB.println("loop done.");
}
```

I am not sure if it is a hardware or software issue, but soldering and tracks are good.

Its like the hardware gets frozen, so I cant really see the serial messages. I know its not a serial issue because I can make a simple print serial script and it shows up. I think it might be related with libraries, or maybe some hardware limitation?

Can I use any pin as Chipselect? is digitalpin17 / A3 right?

title: Arduino Zero and micro SD card not working

Answers: 0


body:
I want this program to receive multiple signals from the elegoo ir remote and produce different tones using the passive buzzer. I have attempted to add onto the basic example provided by adding a makeSound() function.

The serial monitor outputs different values for a button if I hit it multiple times. Is there a way to make it so that each button will give a consistent value so I can keep the pitch the same for each button?

```
#include "IRremote.h"
#include "IR.h"
#include "pitches.h"

IRrecv irrecv(RECEIVER);     // create instance of 'irrecv'
decode_results results;      // create instance of 'decode_results'

void setup() {
  Serial.begin(9600);
  Serial.println("IR Receiver Button Decode");
  irrecv.enableIRIn();
}

void loop()
{
  int tmpValue;
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
        tmpValue = results.value;
        Serial.println(tmpValue);
        makeSound(tmpValue);
    }
    irrecv.resume(); // receive the next value
  }

void makeSound(int tmpValue) {
Serial.println(tmpValue);

  if (tmpValue > 0) {
    Serial.println("In if statement");
    tone(8, NOTE_D5);
    delay(500);
    noTone(8);
  }
  if (tmpValue < 0) {
    Serial.println("In if statement");
    tone(8, NOTE_G1);
    delay(500);
    noTone(8);
  }

}
```

title: Elegoo remote code program only running once

Answers: 0


body:
I'm trying to replace this code with something that uses the Arduino MIDI library:

```
#include <SoftwareSerial.h>

#define rxPin 2
#define txPin 1

SoftwareSerial midiSerial (rxPin,txPin);

void setup() {
  midiSerial.begin(31250); }

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

Here's what I came up with:
```
#include <MIDI.h> // MIDI Output
MIDI_CREATE_DEFAULT_INSTANCE();

byte MIDIChannel;
byte programByte1;
byte controlByte1;
byte controlByte2;

void setup() {
  MIDI.begin();
}

void loop() {
 if (MIDI.read()) switch (MIDI.getType()) {
      MIDIChannel = MIDI.getChannel();
    case midi::ProgramChange:
      programByte1 = MIDI.getData1();
      break;
    case midi::ControlChange:
      controlByte1 = MIDI.getData1();
      controlByte2 = MIDI.getData2();
      break;
    default: break;
    }
}
```

Does that look correct? It doesn't function as smoothly as the version that uses SoftwareSerial

title: Question about MIDI library

Answers: 0


body:
I am working on making an Arduino based arcade. I want each user of the arcade to have an RFID card that stores the amount of credits (basically money) they have. I know that RFID tags have 1028 bytes of storage on them, but I don't know how to write an integer value to them.

The amount of credits each user has would be stored on the RFID, as well as their PIN.

The PIN would be 4 digits, with each digit an integer from 0-9, as is the standard with PINs. It would be stored as a single integer, between 0000 and 9999.

The credit would ALSO be stored on each card. This would be between 0 and 99 (Most that can be loaded at a time). This, too, would be treated as a single integer, for ease of use.

Both integers would be of the Arduino type `int`.

I am using the MFRC522 library with an RC522 reader/writer. I have an Arduino Uno, but can easily switch to an Arduino Nano.

Can someone tell me how to:
A. Write an integer value (stored as a variable in the sketch or accessed from the RFID memory) to an RFID card?
B. Access that information and retrieve it as an integer I could operate on (`+,-,÷,×, etc`)?

Thanks in advance!

title: Store Integer Value of Money on an RFID Tag

Answers: 1

body:
You can read data with :

    status = mfrc522.MIFARE_Read(blockNum, readBlockData, &bufferLen);

and write data by:

    status = mfrc522.MIFARE_Write(blockNum, blockData, 16);

However, there's a lot more to it, so check examples of the RFID library, or this external articles:

https://www.electronicshub.org/write-data-to-rfid-card-using-rc522-rfid/
https://playground.arduino.cc/Learning/MFRC522/

When you read the data in a memory block, you can get the bytes out you need and convert them to an int, or the other way around for writing.