# Question
Title: MCU to switch single coil latching relay not working (attempting array with common gnd)
I have several single coil latching relays, (**EC2-5SNU**).

I am trying to control them by an MCU; connected directly they work fine, but I am iffy about keeping it this way so I'm trying to power them through a darlington pair array, (**ULN2003**).

Using the non-latching type, these work fine through the ULN2003, but attempting to interface the code below with the latching type isn't going so well and i can't figure out why:

```
int right = 12;
int left = 10;

void setup() {
  pinMode(right, OUTPUT);
  pinMode(left, OUTPUT);
}

void loop() {
  digitalWrite(right, HIGH);  //reset
  digitalWrite(left, LOW);
  delay(2000);
  digitalWrite(right, LOW); //set
  digitalWrite(left, HIGH);
  delay(2000);
}

```

I have four connected with a common pin, but to simplify i've tried and failed to have the code above work on a single relay, as shown below:

Measuring the voltages out of the MCU show the correct levels, keeping in mind the ULN2003 acts an inverter, so i've set the boolean logic accordingly.

The voltages at the output of the ULN seem to stick at 0.6V, I've tried a bunch of permutations, including having one pin (on the common pin setup) connected directly to the MCU.

Does anyone have any ideas?

# Answer
> 1 votes
You need to use an h-bridge as if you were driving a motor. For this kind of relay you need to be able to both sink and source current, which a Darlington pair cannot do, it can only sink.

I guess you may be being thrown by the symbol of an inverting buffer used in the schematic symbol for the ULN2803 in your schematic capture package. It's incorrect, since it's not an inverting buffer, it's a Darlington pair:

simulate this circuit – Schematic created using CircuitLab

As you can see, setting the input HIGH will allow the transistor pair to conduct, but setting it to LOW will stop it conducting - so the output is either connected to ground, or is floating.

# Answer
> 1 votes
I'm sure that you've solved this, given that the post is old, but it would work if you use pull-ups on the ULN2003 outputs. However, you should wire at least two open-drain buffers of the ULN2003 to both endings of the relay coil to ensure enough current when the microcontroller pulls down.

See this 2009 EDN post: https://www.edn.com/drive-a-single-coil-latching-relay-without-an-h-bridge-circuit/

---
Tags: arduino-uno, relay, transistor
---


# Question
Title: I develop an earthquake detector but when it detects a movement, the alarm doesn't stop from ringing
This is the code that I used. Actually, I use to code: for Arduino sofware and processing IDE software.

Arduino Source Code/Program:

```
#include<LiquidCrystal.h> // lcd Header
LiquidCrystal lcd(7,6,5,4,3,2); // pins for LCD Connection

#define buzzer 12 // buzzer pin
#define led 13 //led pin

#define x A0 // x_out pin of Accelerometer
#define y A1 // y_out pin of Accelerometer
#define z A2 // z_out pin of Accelerometer

/*variables*/
int xsample=0;
int ysample=0;
int zsample=0;
long start;
int buz=0;

/*Macros*/
#define samples 50
#define maxVal 20 // max change limit
#define minVal -20 // min change limit
#define buzTime 5000 // buzzer on time

void setup()
{
    lcd.begin(16,2); //initializing lcd
    Serial.begin(9600); // initializing serial
    delay(1000);
    lcd.print("EarthQuake ");
    lcd.setCursor(0,1);
    lcd.print("Detector ");
    delay(2000);
    lcd.clear();
    lcd.print("Calibrating.....");
    lcd.setCursor(0,1);
    lcd.print("Please wait...");
    pinMode(buzzer, OUTPUT);
    pinMode(led, OUTPUT);
    buz=0;
    digitalWrite(buzzer, buz);
    digitalWrite(led, buz);
    for(int i=0;i<samples;i++) // taking samples for calibration
    {
        xsample+=analogRead(x);
        ysample+=analogRead(y);
        zsample+=analogRead(z);
    }

    xsample/=samples; // taking avg for x
    ysample/=samples; // taking avg for y
    zsample/=samples; // taking avg for z

    delay(3000);
    lcd.clear();
    lcd.print("Calibrated");
    delay(1000);
    lcd.clear();
    lcd.print("Device Ready");
    delay(1000);
    lcd.clear();
    lcd.print(" X Y Z ");
}

void loop()
{
    int value1=analogRead(x); // reading x out
    int value2=analogRead(y); //reading y out
    int value3=analogRead(z); //reading z out

    int xValue=xsample-value1; // finding change in x
    int yValue=ysample-value2; // finding change in y
    int zValue=zsample-value3; // finding change in z

    /*displying change in x,y and z axis values over lcd*/
    lcd.setCursor(0,1);
    lcd.print(xValue);
    lcd.setCursor(6,1);
    lcd.print(yValue);
    lcd.setCursor(12,1);
    lcd.print(zValue);
    delay(100);

    /* comparing change with predefined limits*/
    if(xValue < minVal || xValue > maxVal || yValue < minVal
            || yValue > maxVal || zValue < minVal || zValue > maxVal)
    {
        if(buz == 0)
            start=millis(); // timer start
        buz=1; // buzzer / led flag activated
    }
    else if(buz == 1) // buzzer flag activated then alerting earthquake
    {
        lcd.setCursor(0,0);
        lcd.print("Earthquake Alert ");
        if(millis()>= start+buzTime)
            buz=0;
    }
    else
    {
        lcd.clear();
        lcd.print(" X Y Z ");
    }

    digitalWrite(buzzer, buz); // buzzer on and off command
    digitalWrite(led, buz); // led on and off command

    /*sending values to processing for plot over the graph*/
    Serial.print("x=");
    Serial.println(xValue);
    Serial.print("y=");
    Serial.println(yValue);
    Serial.print("z=");
    Serial.println(zValue);
    Serial.println(" $");
}

```

Processing IDE Code/Program:

```
import processing.serial.*;
PFont f6,f8,f12,f10;
PFont f24;
Serial myPort; // The serial port
int xPos = 0; // horizontal position of the graph
float y1=0;
float y2=0;
float y3=0;

void setup ()
{
    // set the window size: and Font size
    f6 = createFont("Arial",6,true);
    f8 = createFont("Arial",8,true);
    f10 = createFont("Arial",10,true);
    f12 = createFont("Arial",12,true);
    f24 = createFont("Arial",24,true);
    size(1200, 700);

    // List all the available serial ports
    println(Serial.list());
    myPort = new Serial(this, "COM10", 9600);
    println(myPort);
    myPort.bufferUntil('\n');
    background(80);
}

void draw ()
{
    serial();
}

void serial()
{
    String inString = myPort.readStringUntil('$'); // reading incomming date from serial
    if (inString != null)
    {
        // extracting all required values of all three axis:
        int l1=inString.indexOf("x=")+2;
        String temp1=inString.substring(l1,l1+3);
        l1=inString.indexOf("y=")+2;
        String temp2=inString.substring(l1,l1+3);
        l1=inString.indexOf("z=")+2;
        String temp3=inString.substring(l1,l1+3);

        //mapping x, y and z value with graph dimensions
        float inByte1 = float(temp1+(char)9);
        inByte1 = map(inByte1, -80,80, 0, height-80);
        float inByte2 = float(temp2+(char)9);
        inByte2 = map(inByte2,-80,80, 0, height-80);
        float inByte3 = float(temp3+(char)9);
        inByte3 = map(inByte3,-80,80, 0, height-80);
        float x=map(xPos,0,1120,40,width-40);

        //ploting graph window, unit
        strokeWeight(2);
        stroke(175);
        Line(0,0,0,100);
        textFont(f24);
        fill(0,00,255);
        textAlign(RIGHT);
        xmargin("EarthQuake Graph (SESMIOGRAPH)",200,100);

        fill(100);
        strokeWeight(100);
        line(1050,80,1200,80);

        strokeWeight(1);
        textAlign(RIGHT);
        fill(0,0,255);
        String temp="X:"+temp1;
        Text(temp,100,95);

        fill(0,255,0);
        temp="Y:"+temp2;
        Text(temp,100,92);

        fill(255,0,0);;
        temp="Z:"+temp3;
        Text(temp,100,89);

        //ploting x y and z values over graph
        strokeWeight(2);
        int shift=40;

        stroke(0,0,255);
        if(y1 == 0)
            y1=height-inByte1-shift;
        line(x, y1, x+2, height-inByte1-shift) ;
        y1=height-inByte1-shift;

        stroke(0,255,0);
        if(y2 == 0)
            y2=height-inByte2-shift;
        line(x, y2, x+2, height-inByte2-shift) ;
        y2=height-inByte2-shift;

        stroke(255,0,0);
        if(y2 == 0)
            y3=height-inByte3-shift;
        line(x, y3, x+2, height-inByte3-shift) ;
        y3=height-inByte3-shift;

        xPos+=1;

        if (x >= width-30) // go back to begining
        {
            xPos = 0;
            background(80);
        }
    }
}

void Line(int x1, int y1, int x2, int y2)
{
    float xx1=map(x1,0,100,40,width-40);
    float xx2=map(x2,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    float yy2=map(y2,0,100,height-40,40);

    line(xx1,yy1,xx2,yy2);
    xx2=map(100,0,100,40,width-40);
    yy2=map(0,0,100,height-40,40);
    line(xx1,yy1,xx2,yy2);

    strokeWeight(1);
    for(int i=1;i<21;i++)
    {
        yy2=map(i*10,0,200,height-40,40);
        yy1=yy2;
        line(xx1,yy1,xx2,yy2);
    }
    yy2=map(100,0,100,height-40,40);
    yy1=map(0,0,100,height-40,40);
    for(int i=1;i<41;i++)
    {
        xx1=map(i*5,0,200,40,width-40);
        xx2=map(i*5,0,200,40,width-40);
        line(xx1,yy1,xx2,yy2);
    }

    textAlign(RIGHT); // 100 degree
    // result+=yy1;
    fill(255);
    strokeWeight(1);
    textFont(f12);
    for(int i=-10;i<11;i++)
    {
        String result="";
        result+=5*i;
        ymargin(result, x1,y1);
        y1+=5;
    }

    x1=0;
    y1=0;
    strokeWeight(1);
    textFont(f10);
    for(int i=0;i<41;i++)
    {
        String result="";
        result+=28*3*i;
        xmargin(result, x1,y1);
        x1+=5;
    }

    textAlign(RIGHT);
    textAlign(RIGHT);
}

void ymargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-40,40);
    text(value,xx1-5,yy1+5);
}

void xmargin(String value, int x1, int y1)
{
    float xx1=map(x1,0,200,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1+7,yy1);
}

void Text(String value, int x1, int y1)
{
    float xx1=map(x1,0,100,40,width-40);
    float yy1=map(y1,0,100,height-25,25);
    text(value,xx1,yy1);
}

```

# Answer
> 2 votes
I cannot see anything in your code that could be a cause for this behavior. So maybe the cause is *outside* the code.

How do you simulate an earthquake? I guess you manually move the sensor somehow. It may well happen that, after moving it, it doesn't settle in exactly the same orientation it was before. When this happens, the acceleration of gravity will be in a slightly different direction, and your calibration will not be valid anymore. You can check for this condition by watching the displayed values: if they settle to something almost constant but large (more than 20 in absolute value), then that is what is happening.

If this is the case, a possible solution would be to redo the calibration a couple of seconds after detecting an earthquake. I would suggest a technique that is, in my view, more elegant: calibrate continuously, i.e. update the calibration every few microseconds.

The idea is that, instead of computing a set of offsets once and for all, you low-pass-filter the raw readings and use these smoothed readings as offsets. When you subtract the offsets from the readings, you are implementing in essence a high-pass filter.

Here is a tentative implementation of this idea. I made the readings periodic in order to have some control on the time constant of the filter. In practice, you would have to adapt the time constant to the requirements of your experiment:

```
// Constants to be adjusted, times are in microseconds.
const uint32_t readingPeriod   = 10e3;  // 10e3 us = 10 ms
const float filterTimeConstant = 10e6;  // 10e6 us = 10 s
const float filterConstant = readingPeriod / filterTimeConstant;

// Periodically updated filtered accelerations.
float accelX, accelY, accelZ;

// Internal state of the filter.
uint32_t lastTimeReading = 0;
float offsetX, offsetY, offsetZ;

// Call this from setup()
void initializeOffsets() {
    offsetX = analogRead(x);
    offsetY = analogRead(y);
    offsetZ = analogRead(z);
}

// Call this from loop()
void updateAccelerations() {
    // Take the readings only every readingPeriod us.
    if (micros() - lastTimeReading < readingPeriod)
        return;
    lastTimeReading += readingPeriod;

    // Read the sensors.
    int readingX = analogRead(x);
    int readingY = analogRead(y);
    int readingZ = analogRead(z);

    // Update the offsets.
    offsetX += filterConstant * (readingX - offsetX);
    offsetY += filterConstant * (readingY - offsetY);
    offsetZ += filterConstant * (readingZ - offsetZ);

    // Update the filtered accelerations.
    accelX = readingX - offsetX;
    accelY = readingY - offsetY;
    accelZ = readingZ - offsetZ;
}

```

# Answer
> 2 votes
I would convert the outputs to Integers from Double and see if it's still 'ringing'.

The description suggests it is creating a feedback loop (critically damped) and you have to set a lower limit of those values that also shut the device down.

So, if you are currently reading precision of \< 0.00001 ( in any axis) add a break in the program.

Big old guess but good luck.

# Answer
> 1 votes
Just a guess, but is the vibration from the buzzer sufficiently strong to trigger the accelerometer? If so, once the buzzer sounds after detecting an earthquake, it might just keep triggering itself.

To fix this, you probably need to take some sample accelerometer readings to see how strong the buzzer vibrations are compared to the signal from an earthquake. You could then look to change your calibration or try to filter out the signal from the buzzer.

Alternatively, you might need to physically isolate the buzzer from the accelerometer.

---
Tags: arduino-uno, programming, accelerometer, buzzer
---


# Question
Title: couldn't connect to MQTT broker via esp8266/32 and pub/sub client
I want to use hiveMQ public broker in my project that's the same broker as what available in PubSubClient esp8266 examples but when I change WiFi SSID and password in example and upload it I got this output:

```
Connecting to <SSID NAME>
........
WiFi connected
IP address:
192.168.1.14
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-2 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...

```

**I tried this with pubsub client v2.8/v2.6/v2.4 and esp32 latest version and esp8266 latest version and 2.3**

in response to the comment as I said my code is esp8266\_basic example in the PubSub client examples and here is my code:

```
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

// Update these with values suitable for your network.

const char* ssid = "<SSID>";
const char* password = "<PASS>";
const char* mqtt_server = "broker.mqtt-dashboard.com"; //tested with broker.mqttdashboard.com

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883); //8000 and 1883 tested
  client.setCallback(callback);
}

void setup_wifi() {

  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client")) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      client.subscribe("inTopic");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}
void loop() {

  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 2000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish("outTopic", msg);
  }
}

```

on esp32 I remove `pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output` and

```
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }

```

sections and includes

and sometimes output is like this:

```
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...connected
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...failed, rc=-4 try again in 5 seconds
Attempting MQTT connection...connected

```

# Answer
I found this video as a problem solver, This may help you. All MQTT Errors explained very well and Suggester Different troubleshooting techniques https://youtu.be/CbodTTk-D18
> 2 votes

# Answer
all things are OK and the problem is about my network I think there blocked MQTT (cause I couldn't connect any broker and not just hiveMQ) or other related things cause also my notebook doesn't connect I changed my network provider and the problem fixed

if you ran into the same issue, check other stuff and finally check with a computer in your network (don't use things like http://www.hivemq.com/demos/websocket-client/)
> 1 votes

---
Tags: esp8266, esp32, mqtt
---


# Question
Title: Arduino RF24 library Delay after write function causes no byte availability
It's about the RF24 library you can find here. http://maniacbug.github.io/RF24/index.html

I transmit data from one Arduino to another using NRF24L01 radios. When I use the write-function on the transmitter arduino (joystick is an array) and after that I put in a delay higher then 10, the available function returns false.

Transmitter

```
radio.write( joystick, sizeof(joystick) );
delay(20);

```

Receiver

```
if(!available())
  print('No data'); // delay > 10 --> No data will be printed

```

Why is it working with a delay of 10 but not above? Has it something to do with timeouts which is mentioned in the docs of the library?: http://maniacbug.github.io/RF24/classRF24.html#a4cd4c198a47704db20b6b5cf0731cd58

Thank you for your answers.

# Answer
> 3 votes
In my situation the issue was with the Transmitter not continuing to transmit after a delay. I was able to resolve the issue using the powerDown (http://maniacbug.github.io/RF24/classRF24.html#aa0a51923a09ba4f3478aba9be0f8a6a1) and powerUp (http://maniacbug.github.io/RF24/classRF24.html#a5cdaf47aa0edd6dca1b9a8bb7972a1a3) functions. Here is a snipet of my code. "radioTx" is the name assigned to my transmitter.

```
//standard code setup for arduino uno board examples
radioTx.begin();
radioTx.setChannel(108);
radioTx.openWritingPipe(pipe);

}

void loop() {

  int dist_cm = sonar.ping_cm();

  Serial.println(dist_cm);
  radioTx.write(&dist_cm,sizeof(dist_cm));
  radioTx.powerDown();
  delay(5000);
  radioTx.powerUp();

  }

```

# Answer
> 1 votes
I had the same problem. My solution is:

First make `.stopListening()`

then `.write(&data, sizeof(data))`

and behind the `write` command an `.startListening()`.

Now you can delay for longer times.

# Answer
> 1 votes
Try using

```
unsigned long t = millis();
while(millis() - t < DELAY);

```

instead of "delay(DELAY)"

# Answer
> 0 votes
Please read this: Arduino NRF24L01+ arduino to netmf transmit issue
Although you are not using NETMF, @PhilVallone uses the library and chip together successfully, points out the samples are not asynchronous, and addresses time-out. The OP for that question is using delay(1000) and no answer has been accepted.

# Answer
> 0 votes
Try updating your library to the new TMRh20 fork. That improves the old maniacbug's version a lot (possibly also fixing the bug). tmrh20.github.io/RF24

It's also worth noting that after you've read the message, it will print out "no data" until you receive new message.

---
Tags: nrf24l01+
---


# Question
Title: Servo motor (HSR-1425R) not running continuously
I'm trying to programme a servo motor to reach certain positions. I have a 360 degrees servo motor, so I can not use the Servo library and I can only control the speed. Therefore I want to regulate the time for the pulse. The setup is simple, 5 V, GND and pin 9 from the Arduino to the motor.

```
int servo1 = 9;

void setup{
    Serial.begin(9600);
    pinMode(servo1, OUTPUT);
}
void loop{
    digitalWrite(servo1, HIGH);
    delay(5000);
    Serial.println(digitalRead(servo1));
    digitalWrite(servo1, LOW);
    delay(5000);
    Serial.println(digitalRead(servo1));
}

```

Expected: I expect the code to run the servo motor at full speed for 5 seconds.

Actual: The motor runs at the first impulse and pauses for 10 seconds.

How can I improve the code to do what I expect?

# Answer
Apply some impulse which you need your servo to work on
> 1 votes

# Answer
Look at how servo motors are typically controlled. As far as I know there are no servos that can just be "enabled to rotate" like you seem to expect. Usually a servo's position is set by applying a pulse of a specific length. This means you can apply a PWM signal with proper frequency. Then the duty cycle should be proportional to the servos position. From my experience timing is quite critical when controlling a servo, so going the way you do (timing a gpio's output state with `delay()`s) will not work well. You have to use the atmega's hardware modules (which already is the case when using the arduinos digital write) to achieve adequate timing.
> 0 votes

---
Tags: arduino-uno, motor, continuous-servo
---


title: 12V Relay not clicking

text:
# Question
Title: 12V Relay not clicking
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.

# Answer
> 2 votes
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/

---
Tags: arduino-uno
---


# Question
Title: read first line from sd card and save the position for again reading from sd card
I am reading sd card .txt file, I want to read the first line then how to save the position of the pointer for the next line read?

# Answer
You should not need to save the position, the file knows where you last read from. You'd only need to manually save such information if you close the file and re-open it again, which unless you have a good reason is actually a very wasteful operation.

If you really *do* need to you can use the `.position()` and `.seek()` functions:

Save the location:

```
uint32_t pos = myFile.position();

```

Recall the location:

```
myFile.seek(pos);

```

Documentation:
> 3 votes

# Answer
File myFile = SD.open("test.txt", O\_RDWR);

```
if (myFile) {

  while (myFile.available()) {
    int i = 0;
    while (i < myFile.size()) {
      inputString =  myFile.readStringUntil('\n');
      //Serial.print(inputString);
      if (myFile.readStringUntil('\n')) {

```

I have set a size for the loop, every time it returns "I want it to read a new line" but it skips, what could be the reason?

To help with this question, I wanted to show the process I did on the same question. Thank you, I will ask the question elsewhere. I am sending from the serial port when the end of the line is not read twice, during each reading. I'm sending line by line
> 1 votes

---
Tags: sd-card
---


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

# Answer
These look like C2 and C3 in the Arduino UNO R3 schematic. It *sounds* like both are internally shorted.

Assuming that's true, why it would work (partially anyway) on USB but not external power would depend in part on what external voltage had been applied. The voltage seen on the board, and therefore the brightness of your LEDs, depends on the voltage being dropped above their source. That is, it depends on what's happening to the PTC fuse and in the USB host port and cable etc for USB. And in the linear regulator and similar current limiting in series with it. Probably the thermal overload protection in your regulator is shutting it down so hard that the LEDs don't even light. Or whatever event cause this problem happened while you were externally powering it and there's now an open somewhere on the side external powering.

For now it's probably better if you're not continuing to plug it into a PC. If you're going to do that, it's probably better that you have a powered hub that you don't care about in between.

This seems to be the 3.3V regulator. If you're not using 3.3V, you may be able to get a soldering iron and through-heat the capacitors and scrape them off the board and see whether or not the rest of the board, the 5V section, works fine. Before you do that you may want to measure the 5V and 3.3V lines and write down what you get. One or both are probably low. Take note of the USB source you're using. Try taking off the capacitor off the output side of the regulator first, see how things go. Then go for the input side one. From the sounds of it both are bad though. But it can't hurt to go methodically.
> 2 votes

---
Tags: arduino-uno, usb
---


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

**main.cpp**

```
#include "led.h"
#include <Arduino.h>

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

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

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

```

**Led.h**

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

private:
    const int _pin;
};

```

**Led.cpp**

```
#include "led.h"
#include "Arduino.h"

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

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

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

```

# Answer
> 2 votes
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

---
Tags: arduino-uno, c++, led, pins, debugging
---


# Question
Title: How to write nonblocking code, for polling sensor at 100 Hz
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.

# Answer
> 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:

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

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

# Answer
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.
> 3 votes

---
Tags: sensors, c, millis, variables
---


title: DC Motor Acceleration with PWM

text:
# Question
Title: DC Motor Acceleration with PWM
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

# Answer
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.
> 2 votes

---
Tags: arduino-uno, motor, pwm, adc, potentiometer
---


# Question
Title: NodeMCU - use flash button as input in loop()
I couldn't find a proper answer on the net so I came here as a last resort. So I want to use the FLASH button as an input in the `loop()` method.

Is there a way the check if it's pressed or not?

# Answer
> 17 votes
The Flash button on NodeMCU is connected between io `0` and ground. You can use it as a button. Set `pinMode(0, INPUT_PULLUP)` and you will read io `0` LOW if the button is pressed.

NodeMCU schema

To put the module in flashing mode, first the Flash button must be held and the Reset button pushed, only then should the Flash button be released. Normally, the reset to flashing mode is done automatically by esptool before uploading over USB. This uses the circuit connected to serial RST and DTS lines.

# Answer
> 6 votes
I recommend you EasyButton library, you can use pin 0 (D3) in NodeMCU, if you want use a external button module, you can wire your button between D3 pin and GND.

https://github.com/evert-arias/EasyButton

```
#include <EasyButton.h>

// Arduino pin where the button is connected to.
#define BUTTON_PIN 0

// Instance of the button.
EasyButton button(BUTTON_PIN);

// Callback function to be called when the button is pressed.
void onPressed() {
    Serial.println("Button has been pressed!");
}

void setup() {
    // Initialize Serial for debuging purposes.
    Serial.begin(115200);
    // Initialize the button.
    button.begin();
    // Add the callback function to be called when the button is pressed.
    button.onPressed(onPressed);
}

void loop() {
    // Continuously read the status of the button.
    button.read();
}

```

# Answer
> 3 votes
Just to complete the other answers, here is sample Lua code to help you get started

```
inpin=3 -- Select input pin - GPIO0

function pressed()
    print("PRG Pressed")
end

gpio.mode(inpin,gpio.INT,gpio.PULLUP)
gpio.trig(inpin,"down",pressed)

```

When you press the "Flash" or "PRG" button "PRG Pressed" is printed. You can perform additional magic in the function.

Above sample code adapted from this blog post

I am using this board from MakerFocus

# Answer
> 2 votes
I often use it as an input if I need a button input on my boards. After the initial boot sequence it is just another I/O pin.

# Answer
> 2 votes
The top answer only works for me when the Nodemcu is connected via a serial port and the "Serial Monitor" is turned on. (It was frustrating because it would always work whenever I connect up the serial monitor for debugging and then stop working when I disconnect it to run standalone). I think this is because the Nodemcu connects GPIO0 and GPIO16 to the UART's RTS and DTR signals. The buttons only work when those control lines are in the right states and that might not always be the case. See the third page in the schematic at https://github.com/nodemcu/nodemcu-devkit-v1.0/blob/master/NODEMCU\_DEVKIT\_V1.0.PDF

---
Tags: esp8266, pins, nodemcu
---


title: Run two stepper at same time

text:
# Question
Title: Run two stepper at same time
I am trying to run two stepper motor at same time with different RPM. I decided to use two rotary encoder for change the RPM separately.

But, I am in problem with driving stepper at same time due to the delay time of the step pulse.

How can I generate separate(different duty cycle) step pulses for stepper motors? It's the main problem that I faced.

I have used some Arduino libraries and all of that library has same system for step pulse generation. But, I couldn't understand those well.

```
void AH_EasyDriver::setSpeedRPM(long RPM)
{
   float DIV = RPM*this->MOTOR_RESOLUTION;
    this->STEP_DELAY =  60000000.0L/DIV;
 }

```

This function calculate the step time for given specific RPM

```
void AH_EasyDriver::move(int NUMBER_OF_STEPS)
{
   while(STEPS > 0) {
    if (micros() - this->LAST_STEP_TIME >= this->STEP_DELAY) {
      this->LAST_STEP_TIME = micros();
      STEPS--;
      stepMotor();
}
}

}

```

This function rotate the motor the motor in STEP\_DELAY using stepMotor() function.

```
void AH_EasyDriver::stepMotor()
{
  digitalWrite(this->STEP_pin, HIGH);
  delayMicroseconds(100);
  digitalWrite(this->STEP_pin, LOW);
  delayMicroseconds(100);
}

```

This function makes **CONSTANT** step pulses.

I removed some lines in the function. This is the link for original .cpp file. All of stepper controlling libraries has this functions. I couldn't understand how this functions can change the RPM. Can someone explain this?

# Answer
When using a normal stepper driver, you say the driver to do one step, by sending him one pulse. The length of these pulses does not have a meaning. they are constructed, so that the driver can sense them. The driver does not make smaller steps than 1 full step, if you don't tell him on extra pins (The library you use can utilize those pins too). So the `stepMotor()` function is correct. You can drive the motors with different speeds by doing a step for each motor in different intervals (different number of steps per time).

Your `move()` function blocks the execution of other code, until the motion is completed. You are doing this with the `while( STEPS > 0 )` loop. You need to modify your code to be non-blocking. This is normally done in the way, that is shown by the `BlinkWithoutDelay` example of the Arduino IDE. You are using it too: You have to use the `millis()` or `micros()` function, to check if it is time to do a step.

Replace the `while` with an ´if´-statement:

```
if( STEPS > 0 )

```

and make the `STEPS` variable a member variable of the class instance. Then make sure you execute the function often enough, so that it will not miss the time to do a step. Do the same with the second motor. For example something that looks like this:

```
void setup(){
  ...
  stepper1.doSteps(100);
  stepper2.doSteps(200);
}

void loop(){
  stepper1.move();
  stepper2.move();
}

```

Here in the `setup` function the steppers are told to move `100` and `200` steps. (You would have to write the function `doSteps(int number_of_steps)` yourself). The motion is then done by the `move()` functions, when it is time to do so. Since these two functions are looped very fast, they shouldn't miss the time for a step.

This is also the way the `AccelStepper` library works, which is also a common stepper library.
> 3 votes

# Answer
The method to produce simultaneous pulses is simple, but requires a different approach similar to Direct Digital Synthesis (DDS).

1. Keep one counter variable per motor
2. Increment each counter variable by a set amount in a fixed time loop
3. When a counter variable reaches a threshold value, generate a very short step pulse
4. When a threshold is met, subtract the threshold value from the corresponding counter

The amount that each counter variable is incremented sets the generated pulse rate, reaching the threshold faster or slower, therefore setting the motor speed. A value of 0 stops the motor, a value equal to the threshold generates a step pulse for each iteration of the loop, reaching the highest speed. An arbitrary number of motors may be controlled simultaneously as long as the code can run within the fixed loop time. Since a step can only occur at fixed intervals, the rate of the timed loop should be several times the fastest step rate you intend to use to minimize timing jitter.

This style of control is often implemented using a timed interrupt service routine (ISR) which is a short function set to repeat at a several kHz frequency, interleaving with the rest of the program. This allows a slower loop to run a control algorithm simultaneous to the step generation.

If not using a timed interrupt function, the step generation loop must busy-wait until a set time has elapsed before repeating again. This means you cannot do much else than drive the motors until you stop and break out of the loop.
> 2 votes

---
Tags: arduino-uno, motor, stepper
---


title: ESP32 send data while blinking LED

text:
# Question
Title: ESP32 send data while blinking LED
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

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

Look the example "Let's multitask: Blink with Hello" here, is that what you want.

Read the documentation 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.
> 1 votes

---
Tags: esp32
---


# Question
Title: Why am I getting Invalid head of packet (0xF0) error when trying to upload code to esp8266?
**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 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.

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.

# Answer
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.
> 0 votes

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


# Question
Title: What is the function of the XBee / USB switch on an XBee shield?
I recently bought an XBee shield (this). The shield has a switch that seems to switch between USB/XBee. However, there is no USB port. What exactly is the switch supposed to do?

# Answer
In case someone does ask the same question in the future, this is the explanation for the USB/XBee switch functionality on the XBee Pro Shield V3

The switch serves to connect/disconnect the XBee Pro shield v3 to the Hardware TX-\>1 & RX\<-0 Lines of the Arduino. Moving the switch to the USB side, allows you to disconnect the XBee Pro shield v3 from the hardware serial lines and upload code to your Arduino. If the switch is on the XBee side, this allows your XBee Pro shield v3 to use the TX-\>1 and RX\<-0 lines of the Arduino and if you want to upload code to your Arduino, you would have to remove the shield otherwise it would result in an error trying to upload code.
> 2 votes

# Answer
Better to check connection with tester. I think it switches connection to bluetooth module directly to your PC (with usb serial converter which is on arduino board) or with arduino microcontroller.
> 1 votes

# Answer
I imagine that the switch has the same functionality as the "serial select" switch on the official Arduino Wireless Shield for XBee modules. Therefore the explanations on the switch settings given there (http://www.arduino.cc/en/Main/ArduinoWirelessShield) probably apply also to your board.
> 1 votes

# Answer
The Xbee shield has aswitch labled Xbee/USB. This determines how the Xbee's serial communication connects to the serial communication between the microcontroller (ATmega8 or ATmega168 or Atmega328) and FTDI USB-toserial chip on the Arduino board.

In the Xbee position the Xbee module is connected to the RX pin of the microcontroller; and DIN is connected to TX. Note that the RX and TX pins of the microcontroller are still connected to the TX and RX pins (respectively) of the FTDI chip - data sent from the microcontroller will be transmitted to the computer via USB as well as being sent wirelessly by the Xbee module. The microcontroller, however, will only be able to receive data from the Xbee module, not over USB from the computer.

In the USB position, the DOUT pin the Xbee module is connected to the RX pin of the FTDI chip, and DIN on the Xbee module is connected to the TX pin of the FTDI chip. This means that the Xbee module can communicate directly with the computer - however, **IMPORTANT** this only works if the microcontroller has been removed from the Arduino board. If the microcontroller is left in the Arduino board, it will be able to talk to the computer normally via USB, but neither the computer nor the microcontroller will be able to talk to the Xbee module.

THANKS TO RS-COMPONENTS FOR THE DETAILS!!!!!
> 1 votes

---
Tags: serial, xbee, usb
---


# Question
Title: Store Integer Value of Money on an RFID Tag
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!

# Answer
> 1 votes
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.

---
Tags: arduino-uno, rfid, data-type
---


# Question
Title: Assistance with PID DC Motor Acceleration
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.

```
#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:

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

# Answer
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, which already handles the calculation for you. You just need to call it correctly (refer to the examples of the library).
> 1 votes

# Answer
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:

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

```

This will read the next 3 bytes:

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

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

---
Tags: arduino-uno, motor, potentiometer, midi, pid
---


title: What is the chip in this board?

text:
# Question
Title: What is the chip in this board?
Doing some research about SD card adapters, I found these boards with a chip on them.

They are actually very common. They have a linear voltage regulator because UNO for example use 5V but SD card adapters use 3.3V. The voltage regulator has two capacitors one on the input one on the output. but what is C3? Looks like it is between the output and GND.

The other question is what is the other chip? I guess it turns sd card signals from 3.3 to 5v and viceversa. What is the name of this and what could be this chip model?

# Answer
> **but what is C3? Looks like it is between the output and GND.**

C3 is likely a 10 uF cap for the 3v3 output of the regulator.

(Source: datasheet for Sunrom SD module (PDF))

> The circuit design used in the AMS1117 series requires the use of an output capacitor as part of the device frequency compensation. The addition of 22µF solid tantalum on the output will ensure stability for all operating conditions. When the adjustment terminal is bypassed with a capacitor to improve the ripple rejection, the requirement for an output capacitor increases. The value of 22µF tantalum covers all cases of bypassing the adjustment terminal. Without bypassing the adjustment terminal smaller capacitors can be used with equally good results.

(Source: datasheet for AMS1117 voltage regulator (PDF))

---

> **The other question is what is the other chip? I guess it turns sd card signals from 3.3 to 5v and viceversa. What is the name of this and what could be this chip model?**

At least some of these modules use the LVC125A quad bus buffer gate.
> 6 votes

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


# Question
Title: Unwanted ghosting with charlieplexed LEDs
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:

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:

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?

# Answer
> 5 votes
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:

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

# Answer
> 1 votes
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**

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

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

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 I put on GitHub.

---
Tags: code-review
---


title: Detect button press in a loop

text:
# Question
Title: Detect button press in a loop
I am designing simple "Simon Says game" using Arduino. Simon says is a game in which a LED pattern is played and user has to mimic the pattern. There are 10 Rounds. First Round = 1 led, second round = 2 leds and so on. When the first round is played, one led blinks and player has to press the corresponding button. Then if it presses the right button, next round plays in which two LEDs glow and player has to press 2 buttons in sequence. I am having problem in detecting the button press in a loop for more than 1 round. Here is snippet of the code:

```
void loop() {
  for (int i = 1; i <= ROUNDS; i++)
  {
    digitalWriteGeneric(i);
    bool wait = 1;
    int expected = Sequence[i - 1];
    while (wait)
    {
      int value = digitalReadGeneric();
      if (expected == value)
      {
        Serial.print("Right");
        wait = 0;
        break;
      }
    }
  }
}
int digitalReadGeneric()
{
  for (int i = 0; i < NUM_LIGHTS; i++)
  {
    Readings[i] = digitalRead(buttonPin[i]);
    if (Readings[i] == 1)
    {
      return i;
    }
  }

}

```

Here, ROUNDS = 10 digitalwritegeneric is working fine, it plays the pattern for corresponding pattern. For round more than one how can i detect button press in sequence?. Kindly tell, what I am doing wrong.

# Answer
Looking into your `for`-loop:

```
for (int i = 1; i <= ROUNDS; i++)
  {

    // Write sequence
    digitalWriteGeneric(i);

    // Read sequence
    bool wait = 1;
    int expected = Sequence[i - 1];
    while (wait)
      {
        int value = digitalReadGeneric();
        if (expected == value)
          {
            Serial.print("Right");
            wait = 0;
            break;

            // Setting vlag to false will exit the while loop
            // break will also exit the while loop
            // so only need to do 1 of the 2
            // but then you won't be able to read anymore, it exited the while-loop
          }
      }
  }

```

You only check the first button, and if this one is correct you go out of the `while` loop, ending the reading.

You can change the type of variable `wait` to an `uint8_t` (init to `0`) and if the `value` is right, increment `wait`. The while-loop becomes: `while (wait < i) {}`. You can use `break` to stop reading when the player clicked a wrong button.

To see if the player did the sequence correctly: `if (wait == i) {"GOOD";} else {"BAD";}`
> 1 votes

---
Tags: arduino-uno, button, loop
---


# Question
Title: how to use switch case with two push buttons, I don't know how to combine buttonState1 and buttonState2
```
import muvium.compatibility.arduino.*;

public class Class0 extends Arduino{

/*
Author: First Name MI. Last Name
Date: June 25, 2021
Title: Arduino Experiment 2
Description: Writing to the Output Pins using the FOR statement

Create a program that will display four different LED sequences having
different transition states repeated at different number of times and
that the whole program will repeat itself continuously

Apply the concept of using funcions for each of the four LED sequences,
 each of which are to be called upon from the main program.

This time simplify the LED sequence functions using FOR control statements
to achieve the required iterations

Pin modes of each LED pins are to be iterated together using a FOR statement

The circuit:
 * LEDs connected from digital pin 4-11, all with respect to ground.
*/
// ---------------------------------------------------------
// Declaration of Global Variables:
  int led1 = 4; // LED1 connected to digital pin 4
  int led2 = 4; // LED2 connected to digital pin 4
  int led3 = 4; // LED3 connected to digital pin 4
  int led4 = 4; // LED4 connected to digital pin 4
  int switchPin1 = 2; // PushButton connected to digital pin 2
  int switchPin2 = 3; // PushButton connected to digital pin 3
  int buttonState1 = 0; // variable for reading pushbutton status
  int buttonState2 = 0; // variable for reading pushbutton status
// ---------------------------------------------------------
  public void setup() {
    // the setup() method runs once, when the sketch starts
    // initialize the digital pins as outputs;

    for (led1 = 4; led1 < 12; led1++) {
      pinMode(led1, OUTPUT); // Configure pin 4 to 11 as outputs
    }
    pinMode(switchPin1, INPUT);// Configure pin 2 as input
    pinMode(switchPin2, INPUT);// Configure pin 3 as input
  }
// ---------------------------------------------------------
  public void loop() {
    // the loop() method runs over and over again,
    // as long as the Arduino has power

    // read the state of pushbutton value
    buttonState1 = digitalRead(switchPin1);
    buttonState2 = digitalRead(switchPin2);

    switch (buttonState1) {
      case (0):
        for (led1 = 7, led2 = 8; (led1 > 3) && (led2 < 12); led1--, led2++) {
        digitalWrite(led1, HIGH); // set the LED on
        digitalWrite(led2, HIGH); // set the LED on
        delay(500); // wait for 500 milliseconds
        digitalWrite(led1, LOW); // set the LED off
        digitalWrite(led2, LOW); // set the LED off
        }
        break;

      case 1:
        for (led1 = 11, led2 = 9, led3 = 7, led4 = 5; (led1 > 9) && (led2 > 7) && (led3 > 5) && (led4 > 3); led1--, led2--, led3--, led4--) {
        digitalWrite(led1, HIGH); // set the LED on
        digitalWrite(led2, HIGH); // set the LED on
        digitalWrite(led3, HIGH); // set the LED on
        digitalWrite(led4, HIGH); // set the LED on
        delay(500); // wait for 500 milliseconds
        digitalWrite(led1, LOW); // set the LED off
        digitalWrite(led2, LOW); // set the LED off
        digitalWrite(led3, LOW); // set the LED off
        digitalWrite(led4, LOW); // set the LED off
        }
        break;

      case 2:
        for (led1 = 11, led2 = 10, led3 = 9, led4 = 8; (led1 > 6) && (led2 > 5) && (led3 > 4) && (led4 > 3); led1-=4, led2-=4, led3-=4, led4-=4) {
          digitalWrite(led1, HIGH); // set the LED on
          digitalWrite(led2, HIGH); // set the LED on
          digitalWrite(led3, HIGH); // set the LED on
          digitalWrite(led4, HIGH); // set the LED on
          delay(500); // wait for 500 milliseconds
          digitalWrite(led1, LOW); // set the LED off
          digitalWrite(led2, LOW); // set the LED off
          digitalWrite(led3, LOW); // set the LED off
          digitalWrite(led4, LOW); // set the LED off
          }
          break;

      default:
        for (led1 = 11, led2 = 4; (led1 > 7) && (led2 < 8); led1--, led2++) {
          digitalWrite(led1, HIGH); // set the LED on
          digitalWrite(led2, HIGH); // set the LED on
          delay(500); // wait for 500 milliseconds
          digitalWrite(led1, LOW); // set the LED off
          digitalWrite(led2, LOW); // set the LED off
          }
    }
  }
}

```

# Answer
I don't know what that code is, but it's not Arduino code. It looks like it's wrapped in some other class. But in *real* Arduino code...

To "combine" your two button states it helps to think of them as two individual bits within a byte. A byte is made up of 8 bits, and any of them can be on or off. If you associate your two buttons with two of those bits you can represent them as a single number in a byte.

For example if you use:

```
uint8_t buttonStates = (digitalRead(switchPin2) << 1) | digitalRead(switchPin1);

```

you create a single variable containing both states. In simple terms that means "Read switchPin2, shift the result one bit to the left, then read switchPin1 and superimpose the two results together".

So the result is a byte where bit 1 is switchPin2 and bit 0 is switchPin1.

It gives you, then, a truth table of:

```
SP1 | SP2 | Variable
----+-----+----------
 0  |  0  | 0b00000000
 1  |  0  | 0b00000001
 0  |  1  | 0b00000010
 1  |  1  | 0b00000011

```

Which of course is the numbers 0-3 in decimal.

So then you can use a switch:

```
switch (buttonStates) {
    case 0: // switchPin1 == 0, switchPin2 == 0
        // do something
        break;
    case 1: // switchPin1 == 1, switchPin2 == 0
        // do something
        break;
    case 2: // switchPin1 == 0, switchPin2 == 1
        // do something
        break;
    case 3: // switchPin1 == 1, switchPin2 == 1
        // do something
        break;
}

```
> 1 votes

---
Tags: programming
---


# Question
Title: Arduino nano BLE sense Serial port Suddenly stopped working
Last week I got my new Arduino nanao ble sense. Today I was executing a code on it which reads every sensor data on it and print it on serial monitor. I changed some parameters in my code and upload my code, while the code was uploading I opened the serial monitor and code was fully uploaded. Suddenly i got an error on terminal saying cannot find upload port. After that my Arduino board was never detected by the system. I tried to $lsusb to check whether the device is mounted on usb port but it didn't show up.... I tried on different PC and even that not detected... Plzz let me know if my hardware is damaged in someway? OR is there a solution to this???

# Answer
> 1 votes
All that has happened is that you don't have a sketch running. When you have a board with a native USB connection a sketch has to be running to make that USB connection *be* anything.

You corrupted your sketch, so it's not executing.

All you need to do is manually trigger the bootloader to install a new sketch. According to the "Getting started" page:

> NOTE: If the board does not enter the upload mode, please do a double press on the reset button before the upload process is initiated; the orange LED should slowly fade in and out to show that the board is waiting for the upload.

---
Tags: serial, arduino-nano-ble
---


title: Loading code to a mega 2560

text:
# Question
Title: Loading code to a mega 2560
As part of my application, I need to be able to update the code on my mega 2560 in the field with a download from the internet.

I have found this code in the AT Mega 2560 data sheet

```
 ;-the routine writes one page of data from RAM to Flash
 ; the first data location in RAM is pointed to by the Y pointer
 ; the first data location in Flash is pointed to by the Z-pointer
 ;-error handling is not included
 ;-the routine must be placed inside the Boot space
 ; (at least the Do_spm sub routine). Only code inside NRWW section can
 ; be read during Self-Programming (Page Erase and Page Write).
 ;-registers used: r0, r1, temp1 (r16), temp2 (r17), looplo (r24),
 ; loophi (r25), spmcrval (r20)
 ; storing and restoring of registers is not included in the routine
 ; register usage can be optimized at the expense of code size
 ;-It is assumed that either the interrupt table is moved to the Boot
 ; loader section or that the interrupts are disabled
..equ PAGESIZEB = PAGESIZE*2 ;PAGESIZEB is page size in BYTES, not words
.org SMALLBOOTSTART
Write_page:
    ; Page Erase
    ldi  spmcrval, (1<<PGERS) | (1<<SPMEN)
    call Do_spm

    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spm

    ; transfer data from RAM to Flash page buffer
    ldi  looplo, low(PAGESIZEB) ;init loop variable
    ldi  loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256

Wrloop:
    ld   r0, Y+
    ld   r1, Y+
    ldi  spmcrval, (1<<SPMEN)
    call Do_spm
    adiw ZH:ZL, 2
    sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
    brne Wrloop

    ; execute Page Write
    subi ZL, low(PAGESIZEB)       ;restore pointer
    sbci ZH, high(PAGESIZEB)      ;not required for PAGESIZEB<=256
    ldi  spmcrval, (1<<PGWRT) | (1<<SPMEN)
    call Do_spm

    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spm

    ; read back and check, optional
    ldi  looplo, low(PAGESIZEB)   ;init loop variable
    ldi  loophi, high(PAGESIZEB)  ;not required for PAGESIZEB<=256
    subi YL, low(PAGESIZEB)       ;restore pointer
    sbci YH, high(PAGESIZEB)
Rdloop:
    elpm r0, Z+
    ld   r1, Y+
    cpse r0, r1
    jmp  Error
    sbiw loophi:looplo, 1         ;use subi for PAGESIZEB<=256
    brne Rdloop

    ; return to RWW section
    ; verify that RWW section is safe to read
Return:
    in   temp1, SPMCSR
    sbrs temp1, RWWSB     ; If RWWSB is set, the RWW section is not ready yet
    ret
    ; re-enable the RWW section
    ldi  spmcrval, (1<<RWWSRE) | (1<<SPMEN)
    call Do_spmr
    jmp Return

Do_spm:
    ; check for previous SPM complete
Wait_spm:
    in   temp1, SPMCSR
    sbrc temp1, SPMEN
    rjmp Wait_spm
    ; input: spmcrval determines SPM action
    ; disable interrupts if enabled, store status
    in   temp2, SREG
    cli
    ; check that no EEPROM write access is present
Wait_ee:
    sbic EECR, EEPE
    rjmp Wait_ee
    ; SPM timed sequence
    out  SPMCSR, spmcrval
    spm
    ; restore SREG (to enable interrupts if originally enabled)
    out  SREG, temp2
    ret

```

I am trying to convert this to code I can use in my arduino project under wiring. My first question is the register. It looks like `spmcrval` is register 20, but how can I access that register from within my arduino project?

I have found constants like `SPMEN` in the arduino header, but not these register names.

Also, feel free, if you wish, to avoid the drama and say, "Here's the C source code," which will be worth a certain amount of hero worship.

Everything appears to use avrdude and so I'm trying to parse that as well.

# Answer
Only from bootloader section is it possible to write to flash on ATmega2560. Optiboot 8 has a do\_spm function to write to flash. It is accesible over a header file available in examples in the Optiboot GithHub repository.

After the updated application binary is written to free part of the flash by the running application it is necessary to copy the updated application to run location from address 0. This must be done again by the bootloader.

Optiboot builds in MCUdude Mega Core and Mighty Core have Optiboot enhanced with my copy\_flash\_pages function which copies the pages and then resets the MCU.

My ArduinoOTA library uses do\_spm and copy\_flash\_pages function to store and apply uploaded sketch binary. The InternalStorage object can be used to apply a downloaded binary too.
> 3 votes

---
Tags: bootloader, atmega2560, assembly
---


# Question
Title: Quick noob question about connecting 16x2 LCD
In this tutorial the writer used digital pin 2-5 and pin 11 and 12, can I use other I/O pins if I define it in the library?

```
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

```

# Answer
> 2 votes
Yes, you can. There is nothing special about the pins an LCD like this uses, it's just simple IO. You can even use the "Analog" pins for digital IO. The only pins to stay away from, which is a good rule in general, are the TX and RX pins (pins 0 and 1 on the UNO) as they are used for communication with the PC through USB. All the other pins are fare game for something as simple as an LCD.

---
Tags: arduino-uno, lcd
---


# Question
Title: ESP8266 AutoConnect ACSelect selection index
I'm trying to retrieve the current selected/saved index of my `AutoConnectSelect` Right now i'm creating a type that reads the saved json:

```
 AutoConnectSelect& bright = settingsAux["scr_brightness"].as<AutoConnectSelect>();

```

How can i get the index of the element selected in `bright` as an integer?

`bright.value` and `bright.value()` are both invalid in this context.

Any help or insight into how these types work would be appreciated.

# Answer
The member i was looking for is `AutoConnectSelect.selected` I just subtract the value by one to get the index, as `.selected` starts from 1.
> 1 votes

---
Tags: esp8266, json
---