title: Run a part of a code only 4 second

text:
# Question
Title: Run a part of a code only 4 second
I have two different programs written for my Arduino. One control the rockets thrust vector. The other one is for parachute.

I need to first run rotationmatrices() for a 4 second and then parachute.

How could i do that?

Here is my code:

```
//Libraries
#include <Servo.h>
#include <Wire.h>
#include <MPU6050_tockn.h>
#include <AFMotor.h>
#include <I2Cdev.h>

MPU6050 mpu6050(Wire);

const int MPU = 0x68;
int16_t AcX, AcY, AcZ, Tmp, GyX, GyroY, GyroZ;
double PIDX, PIDY, errorX, errorY, previous_errorX, previous_errorY,
       pwmX, pwmY, previouslog, OutX, OutY, OutZ, OreX, OreY, OreZ;
double PreviousGyroX, PreviousGyroY, PreviousGyroZ, IntGyroX,
       IntGyroY, IntGyroZ, DifferenceGyroX, DifferenceGyroY,
       DifferenceGyroZ, matrix1, matrix2, matrix3;
double matrix4, matrix5, matrix6, matrix7, matrix8, matrix9, Ax, Ay;

//Upright Angle of the Flight Computer-Dik durum açısı
int desired_angleX = 0;

//Offsets for tuning
int servoX_offset = 100;

//Position of servos through the startup function
int servoXstart = 80;

//The amount the servo moves by in the startup function
int servo_start_offset = 20;

//Ratio between servo gear and tvc mount
float servo_gear_ratio = 5.8;

double OrientationX = 0;
double OrientationY = 0;
double OrientationZ = 1;
double accAngleX;
double accAngleY;
double yaw;
double GyroX;
double gyroAngleX;
double gyroAngleY;
double pitch;

Servo servoX;

AF_DCMotor motor1(1); // create motor #1
AF_DCMotor motor2(2); // create motor #2
AF_DCMotor motor3(3); // create motor #1
AF_DCMotor motor4(4); // create motor #2

int buzzer = 3;

double dt, currentTime, previousTime, s, p;

//"P" Constants-Orantısal Değişken
float pidX_p = 0;
float pidY_p = 0;

//"I" Constants-Integral Değişken
float pidY_i = 0;
float pidX_i = 0;

//"D" Constants-Türevsel Değişken
float pidX_d = 0;
float pidY_d = 0;

int pos;

//PID Gains
double kp = 0.2;
double ki = 0.0;
double kd = 0.05;

int state = 0;

void setup() {
    Serial.begin(9600);
    Wire.begin();
    mpu6050.begin();
    gyrocalibrate();

    servoX.attach(10);

    motor1.setSpeed(255);
    motor2.setSpeed(255);
    motor3.setSpeed(255);
    motor4.setSpeed(255);

    pinMode(buzzer, OUTPUT);
}

void loop() {
    mpu6050.update();
    //Defining Time Variables-Zaman değişkeni tanımlanması
    previousTime = currentTime;
    currentTime = millis();
    dt = (currentTime - previousTime) / 1000;
    launchdetect();
    rotationmatrices();
    parachute();
}

void parachute() {
    motor1.run(BACKWARD);
    delay(1500);
    motor1.run(RELEASE);
    delay(20000);
}

void gyrocalibrate() {
    mpu6050.calcGyroOffsets(true);
}

void rotationmatrices(x) {
    mpu6050.update();
    PreviousGyroX = IntGyroX;
    PreviousGyroY = IntGyroY;
    PreviousGyroZ = IntGyroZ;

    IntGyroX = mpu6050.getGyroAngleX() * (PI / 180);
    IntGyroY = mpu6050.getGyroAngleY() * (PI / 180);
    IntGyroZ = mpu6050.getGyroAngleZ() * (PI / 180);

    DifferenceGyroX = (IntGyroX - PreviousGyroX);
    DifferenceGyroY = (IntGyroY - PreviousGyroY);
    DifferenceGyroZ = (IntGyroZ - PreviousGyroZ);

    OreX = OrientationX;
    OreY = OrientationY;
    OreZ = OrientationZ;

    //X Matrices
    matrix1 = (cos(DifferenceGyroZ) * cos(DifferenceGyroY));
    matrix2 = (((sin(DifferenceGyroZ) * -1) * cos(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix3 = ((sin(DifferenceGyroZ) * sin(DifferenceGyroX)
            + (cos(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Y Matrices
    matrix4 = sin(DifferenceGyroZ) * cos(DifferenceGyroY);
    matrix5 = ((cos(DifferenceGyroZ) * cos(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * sin(DifferenceGyroX)));
    matrix6 = (((cos(DifferenceGyroZ) * -1) * sin(DifferenceGyroX)
            + (sin(DifferenceGyroZ)) * sin(DifferenceGyroY)
                * cos(DifferenceGyroX)));

    //Z Matrices
    matrix7 = (sin(DifferenceGyroY)) * -1;
    matrix8 = cos(DifferenceGyroY) * sin(DifferenceGyroX);
    matrix9 = cos(DifferenceGyroY) * cos(DifferenceGyroX);

    OrientationX = ((OreX * matrix1)) + ((OreY * matrix2))
                 + ((OreZ * matrix3));
    OrientationY = ((OreX * matrix4)) + ((OreY * matrix5))
                 + ((OreZ * matrix6));
    OrientationZ = ((OreX * matrix7)) + ((OreY * matrix8))
                 + ((OreZ * matrix9));

    Serial.println(Ax);
    OutX = OrientationX * 60;
    Ax = asin(OrientationX) * (-180 / PI);
    pidcompute();
}

void servowrite() {
    servoX.write(pwmX);
}

void pidcompute() {
    previous_errorX = errorX;
    errorX = Ax - desired_angleX;

    //Defining "P"
    pidX_p = kp*errorX;

    //Defining "D"
    pidX_d = kd*((errorX - previous_errorX)/dt);

    //Defining "I"
    pidX_i = ki * (pidX_i + errorX * dt);

    PIDX = pidX_p + pidX_i + pidX_d;
    pwmX = ((PIDX * servo_gear_ratio) + servoX_offset);
    servowrite();
}

void launchdetect() {
    if (mpu6050.getAccZ() > 1) {
        state = 1;
    }
    if (state == 1) {
    }
}

void abortstart() {
    if (OrientationX > 40 || OrientationY > 40) {
        digitalWrite(buzzer, HIGH);
    }
    else if (OrientationX < 40 || OrientationY < 40) {
    }
}

```

# Answer
> 1 votes
you can do it like this using millis it's just an small portion of code just for your understanding you will require some editing for your code.

```
unsigned long milli1;
void setup()
{
}
void loop()
{
     // code before rotationmatrices() function to be active.
     milli1= millis();
     while(millis()-milli1 <= 4000)  //4000milli sec = 4 sec
     {
      rotationmatrices();
     }
     parachute();

}

```

---
Tags: arduino-uno, programming
---


# Question
Title: ATMega328P U Query - does it work straight away on Uno R3
Quick query (I hope).

I have an Arduio R3 board with ATMega328P U on board. It works fine. I bought some new MCUs, ordered **with bootloader**. Same IC designation. Before I dive into my new project I want to confirm they are okay.

So ...............I take the original MCU out of the Arduino R3 and replace it with a new ATMega328P U. Should it work fine straight away? i.e. can I upload simple sketches like Blink?

My problem is that I've done this and none of them work. I get two flashes on the Rx LED on the board, then ArvDude gives me a string of "not in sync" error messages. If I put the original MCU back in then everything works okay again. I don't want to go through the hassle of burning bootloader on chips that supposedly have it, I'd rather send them back.

Are my new MCUs duff? Or is there any other easy way to check them?

Many thanks

# Answer
> 1 votes
The MCU on the Uno R3 comes with a specific bootloader (Optiboot) and fuse configuration (external clock, clock prescaler disabled, bootloader enabled...). You may find some ATmega328Ps on the market that have been specifically configured as drop-in replacements for the one on an Uno. Those should “just work”. If the ones you bought come with a different bootloader or fuse configuration, you may have to re-flash or reconfigure them.

---
Tags: bootloader
---


title: Latency in Websocket

text:
# Question
Title: Latency in Websocket
I am using Websocket, for a communication from my mobile phone to a NodeMCU, and transmitting 4 channel, data, through 4 different Websocket Ports. the NodeMCU control code is here:

```
// ============ By Pritam Pagla ============ //
// The Only Websocket Program is attached within master branch

// NodeMCU SIDE

#include <SoftwareSerial.h>
#include <ArduinoJson.h>     // Preferably use ArduinoJson 5.x, as StaticJsonBuffer object is not defined in further versions
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include<WebSocketsServer.h>

#include "index_NodeMCU_Test1.h";   // Complete Webpage

SoftwareSerial s(D6,D5);          // Rx as D6 and Tx and D5

int16_t throttle_Val = 0;
int16_t yaw_Val = 0;
int16_t pitch_Val = 0;
int16_t roll_Val = 0;

uint8_t num;
WStype_t type;
uint8_t *payload;
size_t length;

//WiFi Connection configuration
const char *ssid = "PriCopter";       // Can choose these anything one wants
const char *password = "01234567";

WebSocketsServer Twebsocket = WebSocketsServer(9001);
WebSocketsServer Ywebsocket = WebSocketsServer(9002);
WebSocketsServer Rwebsocket = WebSocketsServer(9003);
WebSocketsServer Pwebsocket = WebSocketsServer(9004);

ESP8266WebServer server(80);

//================================================

void handleRoot() {
 String s = MAIN_page; //Read HTML contents
 server.send(200, "text/html", s); //Send web page
}

//================================================
//            Setup
//================================================

void setup() {
s.begin(115200);
Serial.begin(115200);
 delay(100);

  //Setup the NodeMCU as an AP
  WiFi.softAP(ssid, password, 1, false, 1);    //Use NodeMCU as an access point

  //If connection successful show IP address in serial monitor
  IPAddress IP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(IP);

  //Initialize Webserver
  server.on("/",handleRoot);

  server.begin();
  Twebsocket.begin();
  Ywebsocket.begin();
  Rwebsocket.begin();
  Pwebsocket.begin();

}

void loop() {
 StaticJsonBuffer<100> jsonBuffer;
 JsonObject& root = jsonBuffer.createObject();

 server.handleClient();
 Twebsocket.loop();
 Ywebsocket.loop();
 Rwebsocket.loop();
 Pwebsocket.loop();

 Twebsocket.onEvent(ThrottleEvent);
 Ywebsocket.onEvent(YawEvent);
 Rwebsocket.onEvent(RollEvent);
 Pwebsocket.onEvent(PitchEvent);

 Serial.print("Throttle:  "); Serial.print(throttle_Val);
 Serial.print("   Yaw:  "); Serial.print(yaw_Val);
 Serial.print("   Pitch:  "); Serial.print(pitch_Val);
 Serial.print("   Roll:  "); Serial.print(roll_Val);

  root["throttle"] = throttle_Val;
  root["yaw"] = yaw_Val;
  root["roll"] = pitch_Val;
  root["pitch"] = roll_Val;

 root.printTo(s);
 Serial.println("   (Sent)");
}

void YawEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      yaw_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void ThrottleEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      throttle_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void RollEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      roll_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

void PitchEvent(uint8_t num, WStype_t type, uint8_t *payload, size_t length){
  if (type == WStype_TEXT){
      pitch_Val = (int16_t)strtol((const char*) &payload[0], NULL, 10);
  }
}

```

and requiring Webpage details is as:

```
const char MAIN_page[] PROGMEM = R"=====(<!DOCTYPE html>
<html lang = 'en'>
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport"
    content="width=950, height=420 initial-scale=1.0"/>
    <meta http-equiv="X-UA-Compatible"
    content="ie=edge"/>
    <title>Drone Remote</title>
    <style>
    body{
      background-color: #333;
      color: 'black';
      display: flex;
      flex-direction: row;
      align-items: center;
      font-family: Arial, Helvetica, sans-serif;
      min-height: 100vh;
      margin:0;
    }
    #canvasL{
      background: #f0f0f0;
      border-radius: 5x
    }
    #canvasM{
      background: #f0f0f0;
      border-radius: 5px
    }
    #canvasR{
      background: #f0f0f0;
      border-radius: 5px
    }

    #source{
      display: none;
    }

    </style>
  </head>
  <body>
    <canvas id="canvasL" width="450" height="420"></canvas>
    <canvas id="canvasM" width="50" height="420"></canvas>
    <canvas id="canvasR" width="450" height="420"></canvas>

    <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAHWElEQVRoQ7WZT2xUVRTGv9vptIBAC6ghbtQYEhtD4kLcsJCNUdOtLUldGKOuujH+STQYDcGQKEFWGv8LIQgMqcrG6AZcGEkwxEjShUFJVxAIaEVsC23nmnN7v+mZM/fOvJm2L3m5b968ee/87vedc++747BC2/vA1iqwfR54aA6Y98CvM8DP7wAXVuKRbjlu+iXQXwX+rgLwAKSVfQ7AfNzleDae0y2ANQeA6aXGsSSQIwuxdUsQ3jls3b0brlRC1fsFIO9r+3w8FjA5PzM9jVP79oUbyH4buPEp0NcpUEcgFYkbgOwP7toF19UFHwOVNgvhfVBoTlq1/zs5iZ8OHhQY2ecPx85pB6otkDHgRwc81gVg8+Ag1g8MABK4Cj4cxyCpSLCX9wFAzhFEWrFcaL3H+KlTuHTxYgCaBV6tAPuLwhQG+QbwJQCy3zc6Cud9gCCIPDBYihZSVmLvM+AApQB4/rb3uD07izNjYwFG8qyyIHzLrchF7iRQlUSQ/Z6REZR6eupArCrMB/a8BDQbVWLQ0oaklzYqIq3A/HnuHK5evhy+l60ITFOQr4FN3cC1coQQNTYPD6PL+wBCVSQnqISoov2f6nlCSODcCRRgAJw/fTq0cu8iMFmQCtCzCrglEAQRRe4cHFwECeUq5oiylM4JgdI9rlWgAgIhSoTqFY9/P3s2gMi9uDVTJgvyLeAFoCeCSCsg/Tt2BBBJ+JoiqmIFOxn/13o+WowAPB+qFWG8xy3vMTE+zqSvy48cTBJkDPC9CoAwArZ+2zaUoq0EhoqwQulKpK3D4ENFikEz+NAqGPl8aWICtxbKccOWgmkAOQZUVwGOIA1A3d1YvWVLqF6ijAZJQQTLxF7W1pFeJ0gIOH6W89evXq1ByHfME0X0QwV4UhM2gJyIagiAKCG7PhZVejdsQHnduqAMQcROtvpIcBIIFUgFz3PTEeTm1BRmqtU6EKl6drOq1IEcBTwDZ/C2JZzkS3njxpAnYV4VS6gERgXEFjr4mahMOBe/k2OeF4BwPu481gmvgTRMA4gEzl1D5YCcc5grlxeDVxYJATFoFaANlJ+ZE/qzHLcFcihayiqyKtqLrYUUZWwA0pMzMVHZ2mBT59sF0eNLTREBySmQUogWk8olg17KErme16C29/V9+F1OkQaQj4G/eoEN2j72WCc8y7GoIT0Rxo0IE2ewdSrZ4Cx0Tr1WOSIgDnj0OPBLUOSjjK1SlUuP9FKC5QaS7KFqLb5bcEpeA8oFn7KTBU9VLZv0AeRDU3ItAEd4rQRnwmFMVG+C8SWpNiqH8mvyiIGm4ORamz+JcaRhtHcecB8AVRt8bmTXE0gmGF9vaTGrjAZJWU+rksq1xDDSCLIf2FsG3rA5oOdYnGdpCNqKd6S9wmzX2EyrRBCriv6siwGn8s1g5oEB966qVtpCdQNfnHfJ97RUmDTGPbXgoBcY4htfLW9SMDmwZhVLwR1yeyMIA9dKMLH1NN6CMEesvawyNndyMNZarfKDMG6PAmHgKTUEQMptmCzGXU8LuASkl4G0xZg31mbMn1RBKGKrGsjbRhGrglZDAARG20rnCKsXYagKxxjaTavRLH9ald262e+b8QVK50eYEMag+a5OACrC/ODNdJ7oRTkNY1XJ2Y0lu1W1qgN53YBIwKxSErROcOaHQISXKpXs4b1dDY4pGA2iS3QKqGCSk+WMewX4vgw8oUusVYMANj/0OGJB7JJparmUABakndyIJI8LyL0OmLCLDFSCCW4hqIiWVye8Hlf0QJmrZlqhopWKz5b3ktCpLwGeuWBLbQ6EakjLB+tFbFpLW4zzsVw1E5g2LRVYaiCjCRDayZZcViyriLZWqhRTFa0IqxnbTiDqQF6MCa8rlAaRoDkl4RjCRNdVy8KkVOFfDbSS/ruhnSqlrr1WAe4KDhkCSn3AnM0LW3L1QGhXLQhhyzBzhYrYfOnUTjo/6jr1WWUvXaV0kmtbtQJJlWJrL6rToRK1/KgDGQE+KwHP6+TW8yqqkRrV9XyLAHqU1xbT1mq3OlngMtB3BLhhbY6dURUNkJrt6sEwlyMaJGWvpahgbZUCec4DX4htUvmhR/Rc1UpVL63IcgDIPXqBtYeB/3i/hpXGYbVCycBTtkotGmsIm/TLBZBSo0ERXqRhNDEninbCaO3FgXG5g89BZEGGgI0OuL5SgSzlvm39rRDHFlkremQpD13u33YBLxwDPk/dt+lfb0PAFQfcXTSg1H8ZzX4rM+6imwe+OgE8k7u+KYj8aCfwhwceaPbAm0WjyVy3tvXv36oAe5pd1hIk2ux+B1xM3WiydRCFrujPXNUP9HyysMbXdCsEwjukqtlyVYRNiTCL/C3Nn7UFEtV5zQHv6eeKKi27LNOfawDcYb5zwMPHgd9aqaC/bxuEPx4CvnPAU/Zh/8R13mZBSPCZvHi5AhxoB6BjRexDhoDVDpjq5OH8zQBQ2r2wqN/x1rEiuScOA9s9cNIBKdvLa/GFbuDpo8D5jqNO/PB/ioZ2+ax3loAAAAAASUVORK5CYII=" alt="" id="source"/>
    <script>
    const canvasL = document.getElementById('canvasL');       // Object for left canvas
const Lctx = canvasL.getContext('2d');

const canvasM = document.getElementById('canvasM');       // Object for Middle canvas
const Mctx = canvasM.getContext('2d');

const canvasR = document.getElementById('canvasR');       // Object for Right canvas
const Rctx = canvasR.getContext('2d');

const LcenterX = (canvasL.width / 2);    // Marking centre for left Joystick
const LcenterY = (canvasL.height / 2);
const RcenterX = (canvasR.width / 2);    // Marking centre for Right Joystick
const RcenterY = (canvasR.height / 2);
const McenterX = (canvasM.width / 2);    // Marking centre for Middle Portion
const McenterY = (canvasM.height / 2);

var Tsocket = new WebSocket('ws://' + window.location.hostname + ':9001/');
var Ysocket = new WebSocket('ws://' + window.location.hostname + ':9002/');
var Psocket = new WebSocket('ws://' + window.location.hostname + ':9003/');
var Rsocket = new WebSocket('ws://' + window.location.hostname + ':9004/');

const image = document.getElementById('source');

var throttle_Val = 0;
var yaw_Val = 0;
var pitch_Val = 0;
var roll_Val = 0;

const throttle = "t";
const yaw = "y";
const pitch = "p";
const roll = "r";

const LJoyStickBall = {         // defining left joystick as an object
  w: 60,
  h: 60,
  x: LcenterX,
  y: LcenterY+195,
  speed: 1,
  dx: 0,
  dy: 0
};
const RJoyStickBall = {         // defining right joystick as an object
  w: 60,
  h: 60,
  x: RcenterX,
  y: RcenterY,
  speed: 1,
  dx: 0,
  dy: 0
};

function drawLeftCenterBall(){      //Drawing the Left Joystick ball
  Lctx.drawImage(image, LJoyStickBall.x-30, LJoyStickBall.y-30, LJoyStickBall.w, LJoyStickBall.h);
}
function drawRightCenterBall(){      //Drawing the Right Joystick ball
Rctx.drawImage(image, RJoyStickBall.x-30, RJoyStickBall.y-30, RJoyStickBall.w, RJoyStickBall.h);
}

function LnewPos() {                    // changing position for keyboard activity
  LJoyStickBall.x += LJoyStickBall.dx;
  LJoyStickBall.y += LJoyStickBall.dy;

  LdetectBoundary();
}

function RnewPos() {                    // changing position for keyboard activity
  RJoyStickBall.x += RJoyStickBall.dx;
  RJoyStickBall.y += RJoyStickBall.dy;

  RdetectBoundary();
}

function LdetectBoundary(){             // defining the boundary for the LeftJoystickCenterBall
  // Left side
  if (LJoyStickBall.x < LcenterX-195) {
    LJoyStickBall.x = LcenterX-195;
  }

  // Right side
  if (LJoyStickBall.x > LcenterX+195) {
    LJoyStickBall.x = LcenterX+195;
  }

  // Top side
  if (LJoyStickBall.y < LcenterY-195) {
    LJoyStickBall.y = LcenterY-195;
  }

  // Bottom side
  if (LJoyStickBall.y > LcenterY+195) {
    LJoyStickBall.y = LcenterY+195;
  }
}

function RdetectBoundary(){             // defining the boundary for the LeftJoystickCenterBall
  // Left side
  if (RJoyStickBall.x < RcenterX-195) {
    RJoyStickBall.x = RcenterX-195;
  }

  // Right side
  if (RJoyStickBall.x > RcenterX+195) {
    RJoyStickBall.x = RcenterX+195;
  }

  // Top side
  if (RJoyStickBall.y < RcenterY-195) {
    RJoyStickBall.y = RcenterY-195;
  }

  // Bottom side
  if (RJoyStickBall.y > RcenterY+195) {
    RJoyStickBall.y = RcenterY+195;
  }
}

function drawDesigns(){               // 4 Convrntric circles and 2 crossed st lines for better interface
  Lctx.beginPath();
  Lctx.lineWidth = 2.5;
  Lctx.moveTo(LcenterX, LcenterY-195);    // Crossing lines on left
  Lctx.lineTo(LcenterX, LcenterY+195);
  Lctx.moveTo(LcenterX-195, LcenterY);
  Lctx.lineTo(LcenterX+195, LcenterY);
  Lctx.arc(LcenterX, LcenterY, 195, 0, Math.PI * 2);   //Concentric circles on Left
  Lctx.arc(LcenterX, LcenterY, 150, 0, Math.PI * 2);
  Lctx.arc(LcenterX, LcenterY, 100, 0, Math.PI * 2);
  Lctx.arc(LcenterX, LcenterY, 50, 0, Math.PI * 2);
  Lctx.stroke();

  Rctx.beginPath();
  Rctx.lineWidth = 2.5;
  Rctx.moveTo(RcenterX, RcenterY-195);    // Crossing lines on Right
  Rctx.lineTo(RcenterX, RcenterY+195);
  Rctx.moveTo(RcenterX-195, RcenterY);
  Rctx.lineTo(RcenterX+195, RcenterY);
  Rctx.arc(RcenterX, RcenterY, 195, 0, Math.PI * 2);   //Concentric circles on Right
  Rctx.arc(RcenterX, RcenterY, 150, 0, Math.PI * 2);
  Rctx.arc(RcenterX, RcenterY, 100, 0, Math.PI * 2);
  Rctx.arc(RcenterX, RcenterY, 50, 0, Math.PI * 2);
  Rctx.stroke();
}
function clearScreen(){             // Clearing the LeftCanvas and RightCanvas on every loop of the Animation
  Lctx.clearRect(0, 0, canvasL.width, canvasL.height);
  Rctx.clearRect(0, 0, canvasR.width, canvasR.height);
}

function ConsoleOUT(a,b,c,d){
   throttle_Val = (405-a);
   yaw_Val = (b-225);
   pitch_Val = (210-c);
   roll_Val = (d-225);
  console.log('Throttle: '+throttle_Val+'    Yaw: '+yaw_Val+'    Pitch: '+pitch_Val+'    Roll: '+roll_Val);
}

function LeftUpdate(){
  clearScreen();                                //Left Joystick
  drawDesigns();
  drawLeftCenterBall();
  drawRightCenterBall();
  LnewPos();
  RnewPos();
  ConsoleOUT(LJoyStickBall.y,LJoyStickBall.x,RJoyStickBall.y,RJoyStickBall.x);
  requestAnimationFrame(LeftUpdate);

}
function RightUpdate(){                                 //Right Joystick
  clearScreen();
  drawDesigns();
  drawLeftCenterBall();
  drawRightCenterBall();
  LnewPos();
  RnewPos();
  ConsoleOUT(LJoyStickBall.y,LJoyStickBall.x,RJoyStickBall.y,RJoyStickBall.x);
  requestAnimationFrame(RightUpdate);
}

function LmoveUp() {                          // For KeyboardActivity
  LJoyStickBall.dy = -LJoyStickBall.speed;
}

function LmoveDown() {
  LJoyStickBall.dy = LJoyStickBall.speed;
}

function LmoveRight() {
  LJoyStickBall.dx = LJoyStickBall.speed;
}

function LmoveLeft() {
  LJoyStickBall.dx = -LJoyStickBall.speed;
}
function RmoveUp() {
  RJoyStickBall.dy = -RJoyStickBall.speed;
}

function RmoveDown() {
  RJoyStickBall.dy = RJoyStickBall.speed;
}

function RmoveRight() {
  RJoyStickBall.dx = RJoyStickBall.speed;
}

function RmoveLeft() {
  RJoyStickBall.dx = -RJoyStickBall.speed;
}

canvasL.addEventListener('touchstart', function(e){         // 'touchstart' event in LeftCanvas
       e.preventDefault();
       canvasL.addEventListener('touchmove', function(e){
              var touchobj = e.touches[0]; // reference first touch point for this event
              LJoyStickBall.x = touchobj.pageX;
              LJoyStickBall.y = touchobj.pageY;
              sendData(throttle,405-LJoyStickBall.y);
              sendData(yaw,LJoyStickBall.x-225);
              }, false)
   }, false)

   canvasL.addEventListener('touchend', function(e){            // 'touchend' event in LeftCanvas
       e.preventDefault();
       LJoyStickBall.x = LcenterX;
       sendData(yaw,0);
    }, false)

canvasR.addEventListener('touchstart', function(e){         // 'touchstart' event in RightCanvas
       e.preventDefault();
       canvasR.addEventListener('touchmove', function(e){
              var touchobj = e.touches[0]; // reference first touch point for this event
              RJoyStickBall.x = touchobj.pageX - (canvasR.width + RJoyStickBall.w);
              RJoyStickBall.y = touchobj.pageY - RJoyStickBall.h;
              sendData(pitch,210-RJoyStickBall.y);
              sendData(roll,RJoyStickBall.x-225);

          }, false)
   }, false)

   canvasR.addEventListener('touchend', function(e){            // 'touchend' event in RightCanvas
       e.preventDefault();
       RJoyStickBall.x = RcenterX;
       RJoyStickBall.y = RcenterY;
       sendData(pitch,0);
       sendData(roll,0);
      }, false)

  function sendData(a,b){

    if(a == throttle){
      Tsocket.send(b);
    }
    if(a == yaw){
      Ysocket.send(b);
    }
    if(a == roll){
      Rsocket.send(b);
    }
    if(a == pitch){
      Psocket.send(b);
    }

    // switch(a){

    //   case throttle:
    //     Tsocket.send(b);
    //     break;
    //   case yaw:
    //     Ysocket.send(b);
    //     break;
    //   case roll:
    //       Rsocket.send(b);
    //       break;
    //   case pitch:
    //       Psocket.send(b);
    //       break;
    //   default:
    //     console.log('Interruption Occured.')
    // }
  }

  document.addEventListener('keydown', function (e) {        // When certain key is pressed down
    if (e.key == 'ArrowRight') {
      LmoveRight();
      sendData(yaw,LJoyStickBall.x-225);
    } if (e.key == 'ArrowLeft') {
      LmoveLeft();
      sendData(yaw,LJoyStickBall.x-225);
    } if (e.key == 'ArrowUp') {
      LmoveUp();
      sendData(throttle,405-LJoyStickBall.y);
    } if (e.key == 'ArrowDown') {
      LmoveDown();
      sendData(throttle,405-LJoyStickBall.y);
    }
    if(e.key == 'w'){
      RmoveUp();
      sendData(pitch,210-RJoyStickBall.y);
    }
    if(e.key == 's'){
      RmoveDown();
      sendData(pitch,210-RJoyStickBall.y);
    }
    if(e.key == 'a'){
      RmoveLeft();
      sendData(roll,RJoyStickBall.x-225);
    }
    if(e.key == 'd'){
      RmoveRight();
      sendData(roll,RJoyStickBall.x-225);
    }
  });
   document.addEventListener('keyup', function (e) {        // When certain key is released
    if (
      e.key == 'ArrowLeft' ||
      e.key == 'ArrowRight' ||
      e.key == 'ArrowUp' ||
      e.key == 'ArrowDown' ||
      e.key == 'w' ||
      e.key == 's' ||
      e.key == 'a' ||
      e.key == 'd'
    ) {
      LJoyStickBall.dx = 0;
      LJoyStickBall.dy = 0;
      RJoyStickBall.dx = 0;
      RJoyStickBall.dy = 0;
      LJoyStickBall.x = LcenterX;
      RJoyStickBall.x = RcenterX;
      RJoyStickBall.y = RcenterY;
      sendData(yaw,0);
      sendData(pitch,0);
      sendData(roll,0);
    }
  });

  LeftUpdate();
  RightUpdate();
    </script>
  </body>
</html>

)=====";

```

Now, I am new to Web based projects and clearly new to Websockets. In the beginning, i used single websocket port and transmitted the data of the four channels as JSON file, but differentiating the data in 4 different channels, increased the speed slighly, but still one problem is consistent throughout, i.e. after a few seconds, (30-35), it starts to achieve latency, and it stays untill the page is not refreshed again. Can someone please suggest any solution for this, as I am using this for controlling my drone, therefore, any unnecessary latency can be dangerous.

For further information, you can see detailed description and similar codes in this repo.

Thanks in advance.

# Answer
> 1 votes
Not really a proper answer, but a few ideas that hopefully could help you debug the issue:

* I doubt using multiple WebSocket servers really helps, as you end up adding more context switching, i.e. you have to loop through all of them even when they have no data to process.
* `SoftwareSerial` tends to be really slow, as it blocks execution of the sketch while it is sending. You may try to disable it, at least while you troubleshoot this latency issue.
* Calling `Serial.print()` on every loop iteration is also going to slow the sketch down until it is no faster than the serial port. Try to print only once in a while, or only when things actually change.
* Both Firefox and Chrome have “developer tools” which should help you diagnose the problem. At the very least you should be able to see whether the slowdown comes from the server or from the client.

---
Tags: arduino-nano, wifi, nodemcu, web-server
---


# Question
Title: How do I generate a graph from Arduino sensor data?
I used a DHT 11 sensor with an Arduino Uno to measure temperature and humidity. I used the following code to print the temperature and relative humidity in Serial Monitor.

```
dht DHT;

#define DHT11_PIN 7

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

void loop()
{
  int chk = DHT.read11(DHT11_PIN);
  delay(1000);
  Serial.print(DHT.temperature);
  Serial.print(" , ");
  Serial.println(DHT.humidity);
  delay(1000);
}

```

The Serial monitor printed the following data values in a list in the order of: time, temperature (Celsius), humidity (percentage).

```
22:17:55.686 -> 25.00 , 55.00
22:17:57.713 -> 25.00 , 55.00
22:17:59.741 -> 25.00 , 54.00
22:18:01.769 -> 25.00 , 54.00
22:18:03.793 -> 25.00 , 55.00
22:18:05.813 -> 25.00 , 54.00
22:18:07.837 -> 25.00 , 54.00
22:18:09.868 -> 25.00 , 55.00
22:18:11.880 -> 25.00 , 55.00
22:18:13.900 -> 25.00 , 55.00
22:18:15.915 -> 25.00 , 56.00
22:18:17.950 -> 25.00 , 56.00
22:18:19.972 -> 25.00 , 56.00
22:18:21.994 -> 25.00 , 56.00
22:18:24.024 -> 25.00 , 56.00
22:18:26.043 -> 25.00 , 56.00
22:18:28.093 -> 25.00 , 55.00
22:18:30.122 -> 25.00 , 55.00
22:18:32.141 -> 25.00 , 55.00
22:18:34.142 -> 25.00 , 55.00

```

I used the PuTTY software to save the sensor data to a CSV file. However, I end up with a few strange numbers at the top before the values start printing properly.

```
25.25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00
25.00 , 53.00

```

Also, when I open the CSV file in Excel, the time values have disappeared, even though they were there in the serial monitor.

What can I do to get the time stamps to show up in my spreadsheet? Additionally, is there a way I can have the graph automatically update as more data is read?

# Answer
> 2 votes
Perhaps the built-in Arduino Serial Plotter is all you need to visualize your data. I wrote a tutorial a while back that might help you.

---
Tags: arduino-uno, programming, sensors
---


# Question
Title: Trying to understand AccelStepper constant speed
I'm starting to learn the AccelStepper library for controlling stepper motors for a project I'm working on. I'm able to get the stepper motors running with the basic examples that use acceleration.

I know for parts or all of project I'll want to use constant speed, so I popped up the constant speed demo: https://github.com/adafruit/Adafruit\_Motor\_Shield\_V2\_Library/blob/master/examples/Accel\_ConstantSpeed/Accel\_ConstantSpeed.ino

```
#include <Wire.h>
#include <AccelStepper.h>
#include <Adafruit_MotorShield.h>

Adafruit_MotorShield AFMS = Adafruit_MotorShield();
Adafruit_StepperMotor *myStepper1 = AFMS.getStepper(200, 2);

void forwardstep1() {
  myStepper1->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper1->onestep(BACKWARD, SINGLE);
}

AccelStepper Astepper1(forwardstep1, backwardstep1);

void setup()
{
   Serial.begin(9600);
   Serial.println("Stepper test!");

  AFMS.begin();  // create with the default frequency 1.6KHz

  Astepper1.setSpeed(50);
}

void loop()
{
   Astepper1.runSpeed();
}

```

(I'm using the adafruit stepper motor wing)

I uploaded it to my arduino and it's working, the shaft is rotating, but it's doing it really slow. I figured this made sense because it's set at a speed of 50, so I tried turning up the speed:

```
Astepper1.setSpeed(200);

```

But the speed still seems to be the same speed. Considering this is a 200 step motor and `setSpeed` is steps per second you'd think this would whip the motor around fairly quick.

I'm positive that this is due to my misunderstanding of how the library works, but I'm having a hard time trying to figure out how to properly use the constant speed methods.

# Answer
> 1 votes
So I ended up doing some source code diving for the AccelStepper library to figure out what the problem was and it turns out there was a missing method call in their example code, specifically a call to `setMaxSpeed` in the setup function:

```
void setup()
{
    Serial.begin(9600); // set up Serial library at 9600 bps
    Serial.println("Stepper test!");

    AFMS.begin(); // create with the default frequency 1.6KHz

    // ! Note that you need to set the max speed, otherwise the stepper motor will
    // ! only step once per interval regardless of what `setSpeed` value you give
    Astepper1.setMaxSpeed(1000);

    Astepper1.moveTo(targetDistance);
    Astepper1.setSpeed(targetSpeed);
}

```

If you look at the `setSpeed` method in the library you'll notice a constraint of the speed value:

The `constrain` method takes in a speed value and then a low and high, which the accelstepper library sets to the private `_maxSpeed` variable. If the speed is outside of that range it will set the value to the low or high value passed in.

This means, if you don't call `setMaxSpeed` the library will use the default `_maxSpeed` value assigned during construction which issss `1.0`:

So, to correctly use the constant speed methods, you need to be sure to include a call to `setMaxSpeed` in your code before calling `setSpeed`, likely in the `setup` function.

I also shot a video explanation to share with my co-workers. You can see it here: https://vimeo.com/438272826

---
Tags: adafruit, stepper
---


title: Pause between switching motor direction

text:
# Question
Title: Pause between switching motor direction
I'm new both to this forum and to Arduino. My robot is comprised of Arduino Uno with Arduino Motor Shield, 12V DC gear motor, and two limit switches. The robot supposed to move endlessly on rails between the two walls back-and-forth. I have it all wired up and am able to switch the directions of the motor's rotation by pushing the limit switches. However, I also want to have a pause between switching of directions:

... Robot moving forward ...

If front limit switch is pushed
Stop motor
Pause 2 seconds
Run motor CCW

... Robot moving backwards ...

If rear limit switch is pushed
Stop motor
Pause 2 seconds
Run motor CW

... Robot moving forward ...

Simple `delay(2000)` doesn't work as the limit switch remains pushed against the wall. I've been trying out `millis()` approach but the fact that limit switch remains pushed (`HIGH`) I can never produce a difference in time needed to trigger an action. I learned about State Machine but not sure if and how this could help my case?

Can anyone please help me in implementing a two second pause between the switching of the motor's direction?

Below is the code that **momentarily** switches the motor's direction when robot reaches the wall and limit switch is pushed.

```
int switchFront_State = 0;
int switchRear_State = 0;

const int ledYellow = 6;
const int ledGreen = 5;

const int switchFront = 4;
const int switchRear = 2;

const int motorDirection = 12;
const int motorBreak = 9;
const int motorPWM = 3;

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

  pinMode(switchFront, INPUT_PULLUP); // Front switch
  pinMode(switchRear, INPUT_PULLUP); // Rear switch

  pinMode(ledYellow, OUTPUT);
  pinMode(ledGreen, OUTPUT);

  // Setup Channel A
  pinMode(motorDirection, OUTPUT); // Motor direction pin
  pinMode(motorBreak, OUTPUT); // Motor break pin
  pinMode(motorPWM, OUTPUT); // Motor PWM pin
}

void runMotorBackward(){ // Motor moving backward
  digitalWrite(motorDirection, LOW);
  digitalWrite(motorBreak, LOW);
  digitalWrite(motorPWM, 128);
}

void motorStop(){ // Stop motor
  digitalWrite(motorBreak, HIGH);
  digitalWrite(motorPWM, 0);
}

void runMotorForward(){ // Motor moving forward
  digitalWrite(motorDirection, HIGH);
  digitalWrite(motorBreak, LOW);
  digitalWrite(motorPWM, 128);
}

void loop(){
  switchFront_State = digitalRead (switchFront);
  switchRear_State = digitalRead (switchRear);

  if (switchFront_State == HIGH){ // If front switch is pressed
    digitalWrite(ledYellow, HIGH); // Yellow LED
    motorStop();
    runMotorBackward();
    } else {
    digitalWrite(ledYellow, LOW);
  }

  if (switchRear_State == HIGH){ // If rear switch is pressed
    digitalWrite(ledGreen, HIGH); // Green LED
    motorStop();
    runMotorForward();
  } else {
    digitalWrite(ledGreen, LOW);
  }
}
```

# Answer
> 3 votes
I think the problem is because there is no delay time after your motor switch its direction, so the robot is stay on position where the switch is pressed. I don't know if this gonna work, but perhaps you can add delay after the direction changed.
But based on your code, I can't find a condition to run if no switch is pressed. For alternative, you can try this

```
int direction_state = 1; //state where robot moves forward

void loop(){

  /*notes that here I assume while robot moving forward,
   *the rear switch is impossible to pressed, so does while
   *robot moving backward, the front switch is impossible to
   *pressed.
   */

  while ((digitalRead (switchRear)==LOW) && (digitalRead (switchFront)==LOW))
  //no switch pressed, loop will break if any switch pressed
    {
      if (direction_state == 1) runMotorForward(); else
                                runMotorBackward();
    }

  //indicator which switch is pressed and start of 2s motor stops
  if (direction_state==1) digitalWrite(ledYellow,HIGH);
  else digitalWrite(ledGreen,HIGH);

  motorStop(); //stop the motor
  delay(2000);

  //indicator 2s motor stops finished
  if (direction_state==1) digitalWrite(ledYellow,LOW); //indicator front switch is pressed
  else digitalWrite(ledGreen,LOW);

  direction_state = -direction_state //toggle the state
  if (direction_state == 1) runMotorForward(); else
                            runMotorBackward();

  delay(2000);

}

```

Feel free to ask if it's not works

# Answer
> 0 votes
You need to make your switch logic edge sensitive rather than state sensitive. (That's the digital electronics term for it.) That means that you need to react to the change from switch off to switch on, not to the switch being on. (Since you're using INPUT\_PULLUP mode, a switch on = LOW.

So:

In your loop, don't use

```
switchFront_State = digitalRead (switchFront);

```

instead, use code like below to detect a switch press:

```
int newSwitchState = digitalRead (switchFront);
if (newSwitchState == LOW && newSwitchState  != switchFront_State) {
    switchFront_State = newSwitchState;
    //Code to handle the limit switch being pressed
} else if (newSwitchState == HIGH && newSwitchState  != switchFront_State) {
    switchFront_State = newSwitchState;
    //Code to handle switch changing to the off state
}

```

You'll probably also need to use millis() to add some debouncing to your switch. (Ignore switch changes unless 10-20 milliseconds has passed, to avoid the switch jittering on and off when it is initially pressed or released.)

---
Tags: motor, arduino-motor-shield
---


# Question
Title: How can I assign the value of a char array to a uint8_t array?
I have a char array variable that has a value. I need to send this value through LoRa. The library I use for the LoRa implementation accepts an array of uint8\_t. How can I pass the value of a char\[\] to a uint8\_t\[\] variable (and the opposite)?

```
if (Udp.parsePacket()) {
  int udp_received = Udp.available();
  char udp_buffer[udp_received + 1];
  Udp.read(udp_buffer, udp_received);
  udp_buffer[udp_received] = '\0';

  uint8_t udp_to_lora[] = "???";
  rf95.send(udp_to_lora, sizeof(udp_to_lora));
  rf95.waitPacketSent();

}

```

I need to pass the **udp\_buffer** to **uint8\_t udp\_to\_lora\[\]**.

# Answer
I don't have a compiler at hand, but you can cast the array as a `char` and `uint8_t` are similar in size:

```
rf95.send((char*) udp_to_lora, sizeof(udp_to_lora));

```
> 0 votes

---
Tags: programming, c++, array, arduino-yun
---


# Question
Title: Global variable changes its value when loop starts again
I have a problem with the global variable calibrationValue. It is initially set with the correct value and is also displayed correctly in the output. As soon as the loop function is restarted, the value of the variable is wrong, although it is not rewritten. Can someone help me please? The following values are printed in the image:

1. new AI value
2. wrong calibrationValue (!)
3. sumOfValues (needed for calculation of calibrationValue) correct
4. numValues (needed for calculation of calibrationValue) correct
5. Text and calibrationValue (correct!)

```
    int op_mode_Pin = 7;                      // Digital input Pin which transmittes the op_mode_Ardui
    int op_mode_Ardui;                        // Operator Mode of Arduino
    int returnValue1 = 12;                    // First digital return value for transmitting box weight
    int returnValue2 = 13;                    // Second digital return value for transmitting box weight

    int sensorPin = A0;                       // Select the input pin for the potentiometer
    long weightValue = 0;                     // Variable to store the value from the sensor
    long calibrationValue = 0;                // Value which is filled in calibration progress
    int numValues = 50;                       // Number of taken values for calculating an average
    int thresBoxWeight = 300;                 // Weight for separating heavy and light boxes

    unsigned long sumOfValues;                // Sum of the taken values
    unsigned long aveOfValues;                // Average of the values

    char stringBuffer[30];                    // Buffer for combining string and variables

    void setup() {
      // Initiate serial communication to screen
      Serial.begin(9600);

      // Initiate some variables
      //weightValue = 0;
      //calibrationValue = 0;
      //numValues = 50;
      //thresBoxWeight = 300;

      // Set the Input Pins for op_mode_Ardui
      pinMode(op_mode_Pin, INPUT);            // sets the digital pin 7 as input

      // Set the Output Pins for Box declaration
      pinMode(returnValue1, OUTPUT);          // sets the digital pin 12 as output
      pinMode(returnValue2, OUTPUT);          // sets the digital pin 13 as output

    }

    void loop() {
      Serial.println(analogRead(sensorPin));
      Serial.println(calibrationValue);
      // Reset of Sum and Average variables for next cycle
      sumOfValues = 0;
      aveOfValues = 0;
      op_mode_Ardui = digitalRead(op_mode_Pin);

      if (op_mode_Ardui == HIGH){
        for (int i=0; i<numValues; i++){
          weightValue = analogRead(sensorPin);                                                  // read the value from the sensor
          sumOfValues = sumOfValues + weightValue;                                              // Build the sum of all values
        }
        Serial.println(sumOfValues);
        Serial.println(numValues);

        calibrationValue = sumOfValues / numValues;
        sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);     // Combine text and variable to output
        Serial.println(stringBuffer);                                                           // print text and variable to screen
        delay(3000);
      }
    }

```

# Answer
This:

```
sprintf(stringBuffer, "Calibration accomplished with value: %d", calibrationValue);

```

is a buffer overflow: the function `sprintf()` is writing a 40-byte string into a 30-byte buffer. Whatever happens to lie in memory right after the buffer will be overwritten by `sprintf()`. Apparently this happened to be `calibrationValue`. You should use `snprintf()` rather that `sprintf()`, as the former is designed to prevent this kind of overflows.

Or better yet, stick with `Serial.print[ln]()`:

```
Serial.print("Calibration accomplished with value: ");
Serial.println(calibrationValue);

```

**Edit**: You may notice that 13108 is the same as 0x3334, which on a little endian architecture is stored in memory as 0x34 0x33. These are the ASCII codes for "43", which is part of what `sprintf()` wrote past the end of the buffer.
> 1 votes

---
Tags: arduino-uno, variables
---


# Question
Title: Powering Arduino and L293D with the same Power Supply
I am relatively new to Arduino and plan to power an Arduino and an L293D Motor Driver with the same 9V power supply as in the diagram below.

I tried to simulate this with Tinkercad, but it seems like Tinkercad always powers the Arduino with an extra USB Cable, so I can't test it with only 1 power supply.

Would the 9V battery power both the Arduino and the L293D in this example?

# Answer
> 0 votes
I don't see any problem. You used the Vin for 9V, and shared grounds.

I suggest using a bypass capacitor (typically 0.1 uF) for the L293D VCC, but I don't have experience with using a L293D.

Also, you need to check if the battery can deliver enough current for both motors and the Arduino.

---
Tags: arduino-uno, power, battery, l293d
---


# Question
Title: using a switch case with a 5-position switch and serial output
I'm trying to get started on developing a menu system for my LCD1602. I have a Parallax 5-position switch (up,down,left,right,center) and I would like to interface the two.

I've been trying to get some code working but I'm kind of lost. I don't have a lot of recent experience with Arduino and could use some advice. I realize that there is a version of the 1602 that comes with a keypad integrated into the circuit but I don't have that model. I have a plain-jane screen and a separate 5-position switch.

I'm also aware that the easiest way to accomplish what I desire is with a resistor network and mapping the ADC values. However, I don't want to make an analog switch, I want to make a digital switch.

Is there any way I can take the pins and put them into an array and then translate that into a switch case statement?

I've tried several different ideas and nothing seems to be working. Forgive the example code, it's hacked together.

below is my code

```
*/

// constants won't change. They're used here to set pin numbers:
char buttonChar1 = 'a';     // the number of the pushbutton pin
const int buttonPin1 = 2;
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int buttonPin4 = 5;
const int buttonPin5 = 6;
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;
int pinsArray[5] = {2, 3, 4, 5, 6};
void setup() {
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(buttonPin4, INPUT);
  pinMode(buttonPin5, INPUT);
}

void loop() {
  // read the state of the pushbutton value:
  buttonState1 = digitalRead(buttonPin1) == 2;
  buttonState2 = digitalRead(buttonPin2) == 3;
  buttonState3 = digitalRead(buttonPin3) == 4;
  buttonState4 = digitalRead(buttonPin4) == 5;
  buttonState5 = digitalRead(buttonPin5) == 6;
  // check if the pushbutton is pressed. If it is, the buttonState is HIGH:

  switch (pinsArray[5]) {
    case 2:    //
      digitalWrite(ledPin, HIGH);
      Serial.println("button1");
      break;
    case 3:     //
      digitalWrite(ledPin, HIGH);
      Serial.println("dim");
      break;
    case 4:    //
      Serial.println("medium");
      break;
    case 5:    //
      Serial.println("bright");
      break;
  }
  }

```

# Answer
> 2 votes
When you want to perform actions in response to button presses, you should take care of reacting to the signal *edges* rather than *levels*. In other words, you perform the action only when the signal changes from `LOW` to `HIGH`, not every time you see it `HIGH`.

You should also read about button bounce, and either implement your own debouncing or use an existing library. Below is an example using Bounce2, but there are other options:

```
#include <Bounce2.h>

const uint8_t pinDim    = 3;
const uint8_t pinMedium = 4;
const uint8_t pinBright = 5;

Bounce buttonDim, buttonMedium, buttonBright;

void setup() {
    buttonDim.attach(pinDim, INPUT);
    buttonMedium.attach(pinMedium, INPUT);
    buttonBright.attach(pinBright, INPUT);
}

void loop() {
    buttonDim.update();
    buttonMedium.update();
    buttonBright.update();

    if (buttonDim.rose()) {
        Serial.println("dim");
    }
    if (buttonMedium.rose()) {
        Serial.println("Medium");
    }
    if (buttonBright.rose()) {
        Serial.println("bright");
    }
}

```

You could also, as suggested in Michel Keijzers' answer, use arrays for the pins and `Bounce` objects. While these would help streamline the calls to `attach()` and `update()`, they will not help with the meaty part of the code, i.e. reacting to the presses. There, I would prefer the button to have descriptive names.

# Answer
> 1 votes
Next time align your code with ctrl-K (after selecting).

And yes, you can heavily optimize your code (for maintainability) using arrays:

Instead of

```
const int buttonPin1 = 2;
const int buttonPin2 = 3;
const int buttonPin3 = 4;
const int buttonPin4 = 5;
const int buttonPin5 = 6;

```

use

```
const int buttonPins[] = { 2, 3, 4, 5, 6 };

```

In software engineering it's normal to start with index 0 (such as an array index).

For the button states:

```
int buttonState1 = 0; // variable for reading the pushbutton status
int buttonState2 = 0;
int buttonState3 = 0;
int buttonState4 = 0;
int buttonState5 = 0;

```

you can use

```
boolean buttonStates[5];
for (uint8_t buttonIndex = 0; buttonindex < 5; buttonIndex++)
{
    buttonStates[buttonIndex]= false;
}

```

Instead of setting the pin modes:

pinMode(buttonPin1, INPUT); pinMode(buttonPin2, INPUT); pinMode(buttonPin3, INPUT); pinMode(buttonPin4, INPUT); pinMode(buttonPin5, INPUT);

Use a for loop:

```
for (uint8_t buttonIndex = 0; buttonindex < 5; buttonIndex++)
{
   pinMode(buttonPins[buttonIndex], INPUT);
}

```

You can combine the two `for` loops above with one.

To read the button states:

```
buttonState1 = digitalRead(buttonPin1) == 2;
buttonState2 = digitalRead(buttonPin2) == 3;
buttonState3 = digitalRead(buttonPin3) == 4;
buttonState4 = digitalRead(buttonPin4) == 5;
buttonState5 = digitalRead(buttonPin5) == 6;

```

Use

```
for (uint8_t buttonIndex = 0; buttonindex < 5; buttonIndex++)
{
   buttonStates[buttonIndex] = digitalRead(buttonPins[buttonIndex]) == buttonPinds[buttonIndex]) ? true : false;
}

```

For the switch, I think you need to keep it as it differs per pin.

And instead of using the value 5 use e.g.:

```
const uint8_t NR_OF_BUTTONS = 5;

```

and use the NR\_OF\_BUTTONS constant everywhere.

Note: I don't have a compiler at hand, so forgive me for any possible compiler errors.

Also, instead of multiple arrays (each of length NR\_OF\_BUTTONS), you can use an array of a struct which contain the pin number and state, but this is maybe beyond the scope of your programming knowledge. The use of arrays is already a huge improvement.

# Answer
> 1 votes
Michael has already given you some excellent advice on how to clean up your code.

Your switch statement does not make much sense. You're switching based on an out-of-range index into an array of constants.

Once you've read the states of all your buttons as outlined by Michael, your loop needs to decide what to do about the state of each switch.

Is this a joystick style switch, where the user can only engage one direction at a time? Or is it possible to press 2 switches at once?

If it's a diamond arrangement of 5 switches with a switch in the middle, the user could press any combination of switches at the same time.

I'd suggest code like this:

```
void loop() {
    if buttonStates[0] == HIGH {
       //code to handle button 0 (pin 2) being pressed
    }

    if buttonStates[1] == HIGH {
       //code to handle button 0 (pin 3) being pressed
    }
    //And so on for the rest of your switches.
}

```

---
Tags: lcd, button, array, switch
---


title: Nodemcu v3 - Power supply via VU pin?

text:
# Question
Title: Nodemcu v3 - Power supply via VU pin?
I want to control two hitec hs55 micro servos via a Nodemcu v3. These need at least 4.8 V power supply acc to data sheet.

**Specs:**

Hs-55 micro servo:

Voltage range: 4.8-6 V

Current Drain - no-load (4.8V): 150 mA

Pulse Amplitude: 3-5V

NodeMCU (v3):

From what I found it seems like it can "reliably supply 600 mA".

3.3V pins (standard)

5 V (pin VU), Directly connected from the USB (?)

From what I understand it is generally a good idea to supply power to servos separately, otherwise the board can be damaged. Is this also the case here or would it be OK to connect the supplies to the servos from the VU pin? I'm thinking that there is a possibility it could be ok since it is directly connected to the USB.

For the signals I will use the normal GPIO pins.

Thank you in advance :-)

# Answer
Supplying the servo from the USB is generally okay, but if it works or not depends on the USB host you use. The data you mention is not relevant, though:

* 150mA are valid under no load, when there is a load the servo will sink more current
* 600mA probably refers to the onboard linear regulator which provides the 3.3V for the ESP. Depending on what the ESP has to do, it may require those 600mA on itsown and the connected circuit.

You can simply try what you suggested, it won't harm the nodeMCU. If it doesn't work the reason is probably the USB host not being able to provide the required current (a fast-charge usb wall charger should work).
> 0 votes

# Answer
The circuit diagram of a NodeMCU shows that there's a schottky diode between **Vusb** (the voltage input supplied by USB) and the Vin pin. This has the effect of reducing the approximate 5V voltage supplied by your typical USB jack/outlet/cable to something slightly lower. In my case, the apple USB charger adapter provides 5.1V but this gets reduced to 4.76V on the Vin pin. This Vin voltage is also quite noisy. I don't know if that will affect your servos. I've run one NodeMCU from the Vin pin of another NodeMCU pin without any trouble.

The schottky diode in the NodeMCU is a 1n5819/SS14/S4(SOD\_323). I'm not certain, but if this is the correct datasheet, it says it can supply 1 amp, which sounds like enough. If I were you, I'd try and see if I could get power directly from the USB source rather than taking it off the NodeMCU pin. It might work off the pin, though. Try and make sure you get a USB that supplies at least 5.1V, though. It's going to be close.

EDIT: I would also add that the NodeMCU will be drawing power, too. If you are drawing 300mA with your servos and 100-150mA with your nodeMCU, that's cutting it pretty close for most USB power sources. A Macbook, for example, can only supply 500mA via a USB port. This article says a NodeMCU can consume up to 400mA under some circumstances.

Generally speaking, I've been told that it's a bad idea to use GPIO pins to drive anything that draws a significant amount of power. I'm thinking you should maybe consider using some kind of servo driver or relay or something.
> 1 votes

---
Tags: nodemcu, servo
---


# Question
Title: SPI communications with an Yost Labs IMU
I am pairing an Arduino UNO with a Yost Labs 3-Space Sensor Nano, the user manual for said sensor can be found here and the user manual for the sensor family here (kinda confusing, Yost Lab's documentation contradicts itself IMO)

This is my code, pretty straight forward (although this is my first time working with SPI). I am 100% sure the wiring is correct, and I have attached a diagram of my wiring here. The logic voltage converter I am using is this

I believe that as per the user manual, this should successfully return 3 floats in 4 bytes each, corresponding to the filtered euler angles of pitch, yaw, and roll. However, all I am reading is bytes full of 0xFF (or 11111111 in binary) which I believe corresponds to null / no command.

Are there any visible errors in my code?

```
#include <SPI.h>

SPISettings settings(6000000, MSBFIRST, SPI_MODE0 ); //variable to hold SPI settings
//Set Slave Select, MOSI, MISO, CLK
const int CSN = 10;
const int SI = 11;
const int SO = 12;
const int CLK = 13;

// Needed to convert the bytes from SPI to float
union u_types {
   byte b[4];
   float fval;
} data[3];  // Create 3 unions, one for each euler angle

void setup() {
 //Set Pin Modes
 pinMode(CSN, OUTPUT);
 pinMode(SI, OUTPUT);
 pinMode(SO, INPUT);
 pinMode(CLK, OUTPUT);
 //Set Slave Select High to Start i.e disable chip
 digitalWrite(CSN, HIGH);
 //Initialize SPI
 SPI.begin();
 //pour a bowl of serial
 Serial.begin(9600);
}

//function to transfer commands through SPI
byte transferByte(byte byteToWrite) {

 byte Result = 0x00;
 digitalWrite(CSN,LOW);
 delay(1);
 Result = SPI.transfer(byteToWrite);
 delay(1);
 digitalWrite(CSN,HIGH);
 return Result;
}

//function to swap endian
void endianSwap(byte temp[4]) {
 byte myTemp = temp[0];
 temp[0] = temp[3];
 temp[3] = myTemp;
 myTemp = temp[1];
 temp[1] = temp[2];
 temp[2] = myTemp;
}

void loop() {
 SPI.beginTransaction(settings);

 // Clear the internal data buffer on the IMU
 byte result = transferByte(0x01);
     Serial.print("Cleared internal buffer. Result: "),Serial.println(result);

 // Send start of packet:
 result = transferByte(0xF6);
      Serial.print("Send start of packet. Result: "),Serial.println(result);

 // Send command (tared euler angles)
 result = transferByte(0x01);
      Serial.print("Send commmand 0x01. Result: "),Serial.println(result);

 // Get status of device:
 result = transferByte(0xFF);
      Serial.print("Status of device. Result: "),Serial.println(result);

 while (result != 0x01) {  // Repeat until device is Ready
   delay(1);
   result = transferByte(0xFF);
   Serial.print("Status of device. Result: "),Serial.println(result);
 }

 // Get the 12 bytes of return data from the device:
 for (int ii=0; ii<3; ii++) {
   for (int jj=0; jj<4; jj++) {
     data[ii].b[jj] =  transferByte(0xFF);
     delay(1);
   }
 }

 SPI.endTransaction();

 for( int mm=0; mm<3; mm++) {
   endianSwap(data[mm].b);
 }

 Serial.print("fval 1:"), Serial.println(data[0].fval);
 Serial.print("fval 2:"), Serial.println(data[1].fval);
 Serial.print("fval 3:"), Serial.println(data[2].fval);

 delay(3000);
}

```

# Answer
You almost certainly shouldn't raise CSN after each byte, only after the entire packet.

Although the data sheet is not explicit the chip select is usually used to frame an entire command. As it is at the moment it keeps starting a new transaction.

I like the comment in the data sheet that "...the 3-Space Sensor will not work properly in outer space or on planets with no magnetic field".
> 0 votes

---
Tags: arduino-uno, spi
---


title: Does a delay in a loop save energy?

text:
# Question
Title: Does a delay in a loop save energy?
I've noticed most example snippets always have a delay in the loop even if it's not needed for proper execution of the program.

I can only assume this is added because people copy and paste without understanding what's going on but it got me thinking if adding a delay could possible save power too.

If I have a loop that checks some inputs for changes could it be possible that adding a `delay(10)` saves some cycles and thus power?

# Answer
No, it burns energy by doing nothing.

You definitively should send your MCU to sleep and wake up on events or use the watchdog timer to wake up after a predefined period of time.
> 17 votes

# Answer
The `delay` function doesn't do anything special. It basically just counts down milliseconds inside a while loop and times it with `micros()`.

```
void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}

```
> 8 votes

# Answer
No, a short delay (up to 100 millis) is usually inserted in a void loop() when you are attached to an external sensor, in order to stabilize the readings. But it has nothing to do with power consumption. As an example, here are lines 49-52 from the example sketch "AnalogInSerialOut":

```
      // wait 2 milliseconds before the next loop
      // for the analog-to-digital converter to settle
      // after the last reading:
      delay(2);

```
> 5 votes

# Answer
The answers above are wrong, at least for NodeMCU 0.9 (ESP-12 board) ESP8266 and I also tested with Firebeetle ESP8266 board. Since I have a USB tester I can check that if the loop method is empty, the boards consume about **70mA-80mA** but during delay(ms) they consume about **20mA-30mA**.

This is the delay function for the boards commented:

```
void __delay(unsigned long ms) {
    if(ms) {
        os_timer_setfn(&delay_timer, (os_timer_func_t*) &delay_end, 0);
        os_timer_arm(&delay_timer, ms, ONCE);
    } else {
        esp_schedule();
    }
    esp_yield();
    if(ms) {
        os_timer_disarm(&delay_timer);
    }
}

```

I have not investigate further why delay function saves so much power consumption.
> 5 votes

# Answer
> could it be possible that adding a delay(10) saves some cycles and thus power?

No, the `delay()` function just pauses the code for the time specified. It's stil running and consuming energy for counting the time and waiting it to finish.

If you need to conserve power, you could adjust your circuit components in a fashion that will save energy, or if you want to save energy on your Arduino, you could use a breadboard setup(Instructions here and here) or make use of the internal watchdog timer to sleep and wake at certain time intervals. More tutorial about watchdog timer is explained here.

Cheers!
> 1 votes

# Answer
I suspect the answer depends on the kind of Arduino you're using.

The ESP8266 is ARM based, and I believe ARM chips include power management circuits, where subsystems are automatically put in low power state when they are not being used. An ARM-based Arduino will likely use a lot less power while executing a delay than while doing other things.

I don't think AVR chips have any sort of power management, so they have all their silicon "lit up" at all times. That said, CMOS logic circuits do use more power when switching states than when idle, so even an AVR-based Arduino will probably use slightly less power while in a delay() function that it will when it's running instructions that use the arithmetic unit, UARTs, and other subsystems of the chip.

You'll get much better power savings by putting your Arduino into sleep mode.
> 1 votes

# Answer
As stated in previous answers, at least on the AVR version of the Arduino core, `delay()` is a busy wait that keeps the CPU running. In his answer, Duncan C correctly states that “CMOS logic circuits do use more power when switching states than when idle”. It is then expected that instructions that switch a large number of gates or flip-flops consume more power than instructions that only switch a few ones.

Out of curiosity, I disassembled a call to `delay()` to see what kind of instructions it executes. I found that the “hot path” is a loop that executes 44 instructions per iteration:

* 23 of them do arithmetic or logic (add, subtract, compare, XOR)
* 13 move data around (register load, register copy, I/O, read RAM)
* 7 alter the program flow (function call, return, jump, conditional branches, conditional skip)
* 1 alters a bit in a status register

I do not know how this compares with “typical” code, but the large proportion of instructions that do arithmetic and logic computations suggests that `delay()` should be way more energy hungry than, say, a long sequence of `nop` instructions. In the end, the only way to know for sure whether `delay()` changes anything to the power consumption of a specific program would be to measure it.

As a side note, an easy way to save some power on AVR boards is to `#include <avr/sleep.h>` and insert a call to `sleep_mode()` at the end of `loop()`. The sleep with not last for long though, as the Arduino core sets Timer 0 to interrupt the CPU every 1024 µs.
> 1 votes

---
Tags: power
---


title: pinout for stm32duino with bluepill

text:
# Question
Title: pinout for stm32duino with bluepill
I am running the blinking LED program with stm32duino, and an STM32. By trial and error, and a bit of debugging, I have worked out the following:

* pin C13 blinks as well as the built in LED (except my external LED is on the built-in LED is off)
* the constant `LED_BUILTIN` equals 17

I found this pinout: https://stm32duinoforum.com/forum/wordpress/wp-content/uploads/2016/07/The-Generic-STM32F103-Pinout-Diagram.pdf

But it says nothing about C13 being pin 17.

Does anybody know where to look to find out where the arduino pins line up to the codes on the board?

# Answer
> 1 votes
OK if this helps anybody, they give you constants for every pin that look like `PC14` for the one that says `C14`, so you don't need to worry about the integers that they assign to the pins.

I mean there are constants named for the yellow boxes on the above diagram.

---
Tags: stm32
---


title: AccelStepper library advanced codes!

text:
# Question
Title: AccelStepper library advanced codes!
I was trying to find out how this library can run multiple stepper motors at the same time, and I saw this important function called...

```
void AccelStepper::setOutputPins(uint8_t mask)
{
    uint8_t numpins = 2;
    if (_interface == FULL4WIRE || _interface == HALF4WIRE)
    numpins = 4;
    else if (_interface == FULL3WIRE || _interface == HALF3WIRE)
    numpins = 3;
    uint8_t i;
    for (i = 0; i < numpins; i++)
    digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));
}

```

why is it using `uint8_t`? and what is a `mask`? and Is this line:

```
digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));

```

sending a step signal to multiple stepper?

# Answer
> 1 votes
The `setOutputPins()` function sets the pins for a pulse for a single stepper. Depending on the used stepper motor a different number of pins has to be set (normal stepper drivers have 2 pins, the ULN2003 and its siblings have 4) in a different way. For that the function first determines the number of pins to use via the `_interface` member variable of the class.

The `mask` parameter contains the states of the pins. Each bit represents one pin. If the corresponding bit is set to 1, the pin will be set to an active state. If not, it will be set to an inactive state. Normally an active state (like I have called it here) is HIGH, an inactive state is LOW. But when working with different stepper drivers, some pins might work with an inverted logic. Thus the value (LOW or HIGH) is inverted, if the pin is marked as inverted in the `_pinInverted` array. This logic is in the line

```
digitalWrite(_pin[i], (mask & (1 << i)) ? (HIGH ^ _pinInverted[i]) : (LOW ^ _pinInverted[i]));

```

The idiom `condition ? expression : expression` represents an embedded if condition. If the condition evaluates to `true`, the first expression is used, else the second expression. With `mask & (1 << i)` we are checking, if the `i`th bit in `mask` is set. If yes, we use the next expression: `HIGH ^ _pinInverted[i]`. Here the `^` bitwise XOR operator is used to invert the value, if `_pinInverted[i]` is set to 1 (and thus marked the pin as inverted). If `_pinInverted[i]` is zero, the value will stay as it is. The handling of the LOW value is similar.

For understanding that better, you might want to read more about bitwise operators, if you haven't already done so.

> why is it \[the `mask` parameter\] using `uint8_t`?

`uint8_t` is the smallest type, that could be used: 1 byte. As each bit represents one pin, and the library supports steppers with up to 4 pins, only 4 bits are needed at max. Thus using the smallest type with 8 bits is sufficient.

> Is this line sending a step signal to multiple stepper?

No, it is setting the pins of a single stepper motor. Each instance of the `AccelStepper` class represents a single stepper motor. Thus every function in it also only talks to one single motor. You haven't really explained, how you want to add the feedback functionality. But you should not change the `AccelStepper` class to handle multiple motors. That does not make sense to me. Each motor has to be controlled individually and this class is there to capsule the work behind that. Thats the idea behind making a class for this.

I guess you want to drive multiple motors, each with it's own feedback loop. So then you first need to change the `AccelStepper` class for supporting that feedback loop. How this is done depends very much on your type of feedback loop. Also the `setOutputPins()` method is not a good place for that. It is a very low level function. You need to start further up in the call chain, maybe in the `step()` method or the `runSpeed()` method (this really depends on how you want to handle the feedback). Also you need to write methods to set up and handle the encoders input. You may need to configure timers and/or interrupts for reading them correctly.

For then supporting multiple stepper motors, you could still look into the `MultiStepper` class. You could change it to fit with your changes in `AccelStepper` or write your own wrapping class. That mostly depends on how you want the multiple steppers to behave.

---
Tags: library, data-type, stepper-motor, digitalwrite
---


# Question
Title: Arduino I2C external 32Kb fram data organization
Hey guys I am a noob when it comes to data structures and storing types of data, I have been recently working on a project where I needed to store long term data for later retrieval. I decided to buy a Adafruit 10$ 32kb i2c fram Which works, it can store a byte Of data per address which I can successfully do, I can also read those bytes on any address no problem.

One issue I first came across was storing floats into the chip which only took bytes, After googling I managed to spit a float using a union successfully and also storing those in a 4 byte array. Now I did this with 3 different float values which means every 4 bytes stored is basically one split float value.

The second issue is how do I retrieve this data in an organized way and also as a float. I found out you can use a union to do the opposite as well. But how do I tell my code to read every 4 bytes and convert back to float?

Is there a system that can allow me to store data in a structured way using the arduino? Like a time stamped data using an external rtc? Such that when I click retrieve it will print that data in an organized fashion.

# Answer
> 3 votes
It'll be easier if you use a `struct`, not a `union`. Store all the data you want to preserve in a struct, then cast a pointer to it to be a `byte` pointer and just treat it as an array of bytes and read and write those bytes to the FRAM.

The `union` you were using explicitly did the same thing, but it's not easy to scale to multiple items.

Some caveats about what you can safely keep in the `struct`:

* do not store pointers in it. A `char` array is fine because the entire array will take up space in the `struct`. A `char *` is not because all you'll save is the value of the pointer, not what it points at.
* do not store objects (like `String`) in it. You don't know (and shouldn't know) how the object is composed internally. If need to use objects, they should have `serialize` and `deserialize` methods which would store or restore the contents of an object into an array of bytes which you could then store or restore with the FRAM.

Also remember that the C/C++ `sizeof` function (used below) tells you the size of thing at compile-time. So if you use it on a `struct` it will tell you the number of bytes it takes to store the `struct`. If you use it on a `char *`, it will tell you the number of bytes in a pointer to a `char`, not the number of bytes in the C string that the `char *` points at. If you use it on an object - like `String str; sizeof(str);` \- it will tell you how many bytes it takes to store the `String` object, which will include the length of the string it stores.

Psuedo-code follows. There are more compact ways to write this; I'm aiming for clarity here.

```
#include <Arduino.h>

struct program_data {
  float first_thing;
  unsigned long second_thing;
  char third_thing[55];
  char fourth_thing;
  uint16_t fifth_thing;
} data;

void save_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for(size_t i = 0; i < sizeof(struct program_data); i++)
    store_byte_in_fram(ptr[i], i);
}

void restore_data(struct program_data *data_ptr) {
  byte *ptr = (byte *)data_ptr;

  for(size_t i = 0; i < sizeof(struct program_data); i++)
    retrieve_byte_from_fram(ptr[i], i);
}

// call when you want to save your data
  save_data(&data);

// call when you want to restore your data
  restore_data(&data);

```

---
Tags: i2c, data
---


# Question
Title: Store & retrieve parameters after sketch update
I have a Generic code for some IOT devices which vary in some parameters ( lets say it is only its MQTT name and subscriptions).

Since I use OTA to update sketch, I'm looking for a way to A) write those parameters into the ESP32/ ESP8266 FS, and B) They will survive an update.

My only solution come into mind is using an SD card which does not get erased after OTA, and I'm looking for a way doing it not involving SD or external memory.

Guy

# Answer
> 2 votes
There is no need for an SD card. You can write all relevant parameters into a file in SPIFFS (e.g. json if you like) before starting the OTA update. During initialization you read the file and set the parameters accordingly. SPIFFS does not get erased when doing an update (at least that's true for the OTA library that I'm using). If it does get erased in your case, there probably is an option in the OTA lib to disable flash erase, just like there is the same option when uploading a sketch via serial.

---
Tags: eeprom, ota, spiffs
---


# Question
Title: If the code used for Arduino can be embedded into a permanent , callable memory, is there a way to create an OS for Arduino that runs on call?
This thought came into my mind on thinking about smartwatches.

Although those I saw on YouTube are really good, they don't seem to provide a real experience of a real smartwatch - one that has an OS embedded in it. If some code in Arduino C/c++ can be compiled into some binary code that works on being called from the flash memory (where the main program resides), is there a possibility that we will be able to make an OS for Arduino ?

# Answer
An AVR-based Arduino is a poor choice for writing an "OS" in the modern sense. It's just too resource constrained. It doesn't have enough RAM, it doesn't have enough flash memory, it's too slow, it doesn't have protected memory or paging, it doesn't have video display, it doesn't have a file system, and on and on.

If you look at an Apple II, something like Apple DOS or ProDos gives you an idea of the sort of thing you can do (minus the video output.)

If you want to develop something like a smart watch an ARM processor is a much better choice. It packs a lot more performance into a small package. You might pick an ARM based Arduino, but you would be fighting against the lack of an OS, the lack of preemptive multi-tasking, etc.

As an alternative, a Raspberry Pi has just about everything you need. It doesn't have as many hardware interfacing options as an Arduino, but a LOT more processing power. Likewise, UNIX is a better choice as the basis for the OS for such a device. It is a protected memory OS that is made to run on relatively modest hardware.
> 0 votes

---
Tags: programming, memory-usage, memory
---


# Question
Title: Fastest Communication from NodeMCU to Arduino Nano
For one of my projects, I need to transmit data from NodeMCU to my Arduino Nano, in real time, I used S-Bus, but it quite unsatisfies me, as, slight latency is taking place. I am transmitting a JSON file, with 4 signed 16 bit integeres.

Now,I need to know, what is the fastest and most reliable way to transmit data from NodeMCU to an Arduino Nano. Any detailed description, or even suggestion will be very much helpful. Thanks in advance !

# Answer
If it comes to speed and reliability you have to choose an interface that is handled in hardware on both sides. For the arduino nano you have the following options (nodeMCU supports all of them):

* UART:
    + not very fast (order of 10kbit/s), but it's full-duplex (asynchronous communication in both directions)
    + implementation is trivial due to `Serial.h`
    + long distance (order of meters)
* I2C:
    + not very fast either (order of 100kbit/s), but not full-duplex
    + implementation is straight forward because both slave and master are implemented in arduino library
    + only over short distance (order of cm)
* SPI:
    + quite fast (\>1Mbit/s), full-duplex
    + implementation might require some experience (as far as I know, slave mode is not supported by `SPI.h`)
    + long distance (order of meters)

Which of those is the best option still depends on your specific requirements, but personally I like SPI very much because it is very fast and stable.
> 0 votes

---
Tags: serial, arduino-nano, nodemcu, softwareserial
---


# Question
Title: Why delay of more than 64 millisecond stops the servo motor from rotating? I am not using "Servo.h" instead i am just managing the length of pulse
The code I used was this

```
int servo = 5;
int angle;

void setup() {

  pinMode(servo, OUTPUT);

}

void loop() {

  for (angle = 0;angle<180;angle++){

    digitalWrite(servo, HIGH);
    delayMicroseconds((angle*(11))+365);
    digitalWrite(servo,LOW);
    delay(65);
  }

  for (angle = 179;angle>0;angle--){

    digitalWrite(servo, HIGH);
    delayMicroseconds((angle*(11))+650);
    digitalWrite(servo,LOW);
    delay(65);

}
}

```

as u can see I have set the delay after a particular step to be 65 milliseconds but it won't work, any delay greater than 64 milliseconds do not work and the motor just stops rotating.

what is the reason for this??

# Answer
A servo motor doesn't just require a single pulse to send it to a specific angle. It requires a constant stream of pulses at the right frequency for it to track what the angle should be.

By sending one pulse you're just hinting where it might like to go to, then stopping. It's never going to get there, unless you keep sending those pulses fast enough.

Also if you don't send pulses then the servo will go into a "low power sleep mode" where it's not actively driving the output and it will go "floppy" where you can move the servo by hand.

Typically you need to send pulses at about 50Hz, which is one pulse every 20ms. Many servos will be more forgiving, but if you send too slowly they just won't know what to do.

If you want to be handling the pulses yourself then you need to do it in the right way. That is:

1. Send a pulse of your desired length
2. Delay for 20ms minus your desired length
3. Go to 1 until your desired elapsed time has been reached.

For example:

```
for (angle = 0; angle<180; angle++){
  uint32_t ts = millis();
  while ((millis() - ts) < 100) { // 100ms delay
    digitalWrite(servo, HIGH);
    delayMicroseconds((angle * 11) + 650);
    digitalWrite(servo,LOW);
    delayMicroseconds(20000 - ((angle * 11) + 650));
  }
}

```

That won't be exact, owing to the latency of the loop instructions, but it will be close enough.
> 2 votes

---
Tags: arduino-uno, sensors, motor, servo, pwm
---


# Question
Title: Instantiate class in the constructor rather in the top end?
Is there a way to define class variables in the constructor or in a method rather than at the top of the document?

I have the following code in my custom library:

```
#include "DHT.h"

// DHT settings.
#define DHTPIN 7 // Digital pin connected to the DHT sensor.
#define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE); // Initialize DHT sensor.

void DhtLib::doSomeStuff() {
  dht.begin();
  float temp = dht.readTemperature();
  ...
}

```

I would like to be able to set the pins with a function. But for this to work I have to find a way to define the `dht` variable in a different place than at the top of the document within the `// DHT settings.`. Best would be in a method such as:

```
void DhtLib::begin(int dhtPin) {
  DHT dht(dhtPin, DHTTYPE);
}

```

This works, but only within this function. I need this to be accessible in the entire document, not just a single function.

How can I achieve that?

**EDIT 1:**

Entire code of the custom DhtLibrary.h file:

```
#ifndef DhtLibrary_h
#define DhtLibrary_h

#if (ARDUINO >= 100)
  #include "Arduino.h"
#else
  #include "WProgram.h"
#endif

class DhtLib {
  private:
    DHT dht;
    float readTemperatureFromDHT();
    float readHumidityFromDHT();
    float calculateHeatIndex(float temperature, float humidity);

  public:
    // Constructor.
    DhtLib(int dhtPin) : dht(dhtPin, DHT22) {}

    // Methods.
    void begin();
    String getHumiTempJson();
};

#endif

```

The error with this above code is:

```
In file included from /home/myuser/Documents/Codes/temperature-control/slave2-arduino/slave2-arduino.ino:2:0:
DhtLibrary.h:12:5: error: 'DHT' does not name a type
     DHT dht;

```

# Answer
> 1 votes
There's numerous ways of doing this. The best is probably to have a DHT object as a class property and set it up with an *initializer list*:

```
#include "DHT.h"

class DhtLib {
    private:
        DHT dht;

    public:
        DhtLib(int dhtPin) : dht(dhtPin, DHT22) {}
        void begin();
        void doSomeStuff();
};

void DhtLib::begin() {
    dht.begin();
}

void DhtLib::doSomeStuff() {
    float temp = dht.readTemperature();
}

DhtLib thing(7);

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

void loop() {
    thing.doSomeStuff();
}

```

---
Tags: arduino-uno, code-review
---


# Question
Title: Is this circuit risky for an Arduino Uno?
I will show a connection diagram between my Arduino Uno and a DSC HS2032 panel (alarm system).

The DSC panel uses 12V and I don't know the voltage fluctuation.

The yellow and green are RX/TX ports.

Github file: https://github.com/taligentx/dscKeybusInterface/blob/master/examples/Arduino/KeybusReader/KeybusReader.ino

DIAGRAM (I assume the vertical "+--+" means a simple "OR" connection):

```
  DSC Aux(+) --- Arduino Vin pin

  DSC Aux(-) --- Arduino Ground

                                 +--- dscClockPin (Arduino Uno: 2,3)
  DSC Yellow --- 15k ohm res ----|
                                 +--- 10k ohm resistor --- Ground

                                 +--- dscReadPin (Arduino Uno: 2-12)
  DSC Green ---- 15k ohm res ----|
                                 +--- 10k ohm resistor --- Ground

```

I need to make sure this diagram is SAFE, and will not overheat or do something risky to my Arduino.

Why is this circuit not going to burn my Arduino if it is using 12V?

# Answer
That circuit is fine as long as the input signals don't go above 12.5V. You can protect it further by adding a 5.2V zener diode across each of the signals as they enter the Arduino:

simulate this circuit – Schematic created using CircuitLab

> Why is this circuit not going to burn my Arduino if it is using 12V?

Because it uses a voltage divider to reduce the voltage to 4.8V.
> 4 votes

---
Tags: electronics, electricity
---


title: Write a Struct using ArduinoBLE library

text:
# Question
Title: Write a Struct using ArduinoBLE library
Hello I'm trying to send some Structs such as:

```
typedef struct __attribute__ ((__packed__)) myohw_command_set_mode {
    myohw_command_header_t header; ///< command == myohw_command_set_mode. payload_size = 3.
    uint8_t emg_mode;              ///< EMG sensor mode. See myohw_emg_mode_t.
    uint8_t imu_mode;              ///< IMU mode. See myohw_imu_mode_t.
    uint8_t classifier_mode;       ///< Classifier mode. See myohw_classifier_mode_t.
} myohw_command_set_mode_t;

```

To another device via BLE using the Arduino BLE library. I have the services and characteristics all set up correctly. My problem is that arduino BLE .writeValue() function expects some specific formats and i'm not quite sure the best way to convert this struct to one of them.

```
  int writeValue(const uint8_t value[], int length);
  int writeValue(const void* value, int length);
  int writeValue(const char* value);
  int writeValue(uint8_t value);
  int writeValue(int8_t value);
  int writeValue(uint16_t value);
  int writeValue(int16_t value);
  int writeValue(uint32_t value);
  int writeValue(int32_t value);

```

What format should i use? And what is the best way to cast the Struct to the format?

Thanks,

# Answer
> What format should i use?

```
int writeValue(const uint8_t value[], int length);

```

> And what is the best way to cast the Struct to the format?

```
writeValue((uint8_t *)&myStruct, sizeof(myStruct));

```
> 1 votes

---
Tags: bluetooth, ble
---


# Question
Title: How to Fix mouse cursor lag on voice & movement based head mouse in wireless setting?
For my head mouse project which is based on the voice recognition module V3.1 for left click, double click, right-click operations, I am facing a problem. I am using 433Mhz Radio Frequency one-way Transceiver for sending data. When I use the MPU 6050 accelerometer and gyroscope for mouse cursor movement and the voice recognition module together on only one Arduino board, the mouse cursor moves smoothly and the voice commands work smoothly. But when I use the 433Mhz RF one-way transmitter for one Arduino board to calculate the mouse movement and figure out the voice command to send it in a wireless manner and receive the values and voice commands using the receiver module of the rf433 Mhz, the mouse cursor starts to lag. It doesn't move smoothly. Please help me solve the problem. The code and circuit diagram are given below:

**Transmitter.ino**

```
  /*433 MHz RF Module Transmitter Demonstration 1
  RF-Xmit-Demo-1.ino
  Demonstrates 433 MHz RF Transmitter Module
  Use with Receiver Demonstration 1

  DroneBot Workshop 2018
  https://dronebotworkshop.com
*/

// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>
#include <SoftwareSerial.h>
#include "VoiceRecognitionV3.h"
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>

VR myVR(8,9);    // 9:RX 8:TX

uint8_t records[7]; // save record
uint8_t buf[64];

MPU6050 mpu;
int16_t ax, ay, az, gx, gy, gz, oax, oay, oaz, ogx, ogy, ogz;
int16_t vx, vy;
//
#define leftRecord    (0)
#define rightRecord   (1)
#define doubleRecord  (2)

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf     --> command length
           len     --> number of parameters
*/
void printSignature(uint8_t *buf, int len)
{
  int i;
  for(i=0; i<len; i++){
    if(buf[i]>0x19 && buf[i]<0x7F){
      Serial.write(buf[i]);
    }
    else{
      Serial.print("[");
      Serial.print(buf[i], HEX);
      Serial.print("]aurav");
    }
  }
}

/**
  @brief   Print signature, if the character is invisible,
           print hexible value instead.
  @param   buf  -->  VR module return value when voice is recognized.
             buf[0]  -->  Group mode(FF: None Group, 0x8n: User, 0x0n:System
             buf[1]  -->  number of record which is recognized.
             buf[2]  -->  Recognizer index(position) value of the recognized record.
             buf[3]  -->  Signature length
             buf[4]~buf[n] --> Signature
*/
void printVR(uint8_t *buf)
{
  Serial.println("VR Index\tGroup\tRecordNum\tSignature");
  Serial.print(buf[2], DEC);
  Serial.print("\t\t");

  if(buf[0] == 0xFF){
    Serial.print("NONE");
  }
  else if(buf[0]&0x80){
    Serial.print("UG ");
    Serial.print(buf[0]&(~0x80), DEC);
  }
  else{
    Serial.print("SG ");
    Serial.print(buf[0], DEC);
  }
  Serial.print("\t");

  Serial.print(buf[1], DEC);
  Serial.print("\t\t");
  if(buf[3]>0){
    printSignature(buf+4, buf[3]);
  }
  else{
    Serial.print("NONE");
  }
  Serial.println("\r\n");
}

struct dataStruct{
  int16_t moveX;
  int16_t moveY;
  int flag;
  }myData;

byte tx_buf[sizeof(myData)] = {0};

// Create Amplitude Shift Keying Object
RH_ASK rf_driver;
int flag = 15;

void setup()
{

   /** initialize */

  Wire.begin();
  mpu.initialize();
  if (!mpu.testConnection()) {
    while (1);
    }

  myVR.begin(9600);
  Serial.begin(115200);
  Serial.println("Elechouse Voice Recognition V3 Module\r\nControl LED sample");

  if(myVR.clear() == 0){
    Serial.println("Recognizer cleared.");
  }else{
    Serial.println("Not find VoiceRecognitionModule.");
    Serial.println("Please check connection and restart Arduino.");
    while(1);
  }

  if(myVR.load((uint8_t)leftRecord) >= 0){
    Serial.println("leftRecord loaded");
  }

  if(myVR.load((uint8_t)rightRecord) >= 0){
    Serial.println("rightRecord loaded");
  }

  if(myVR.load((uint8_t)doubleRecord) >= 0){
    Serial.println("doubleRecord loaded");
  }

    // Initialize ASK Object
    rf_driver.init();
    if(!rf_driver.init()) Serial.println("Init failed");

}

void loop()
{

  int ret;

  ret = myVR.recognize(buf, 50);
    const char *msg = "Welcome to the Workshop!";

  if(ret>0){

  switch(buf[1]){

    case leftRecord:
    flag = 0;
    break;

    case rightRecord:
    flag = 1;
    break;

    case doubleRecord:
    flag = 2;
    break;

    default:
    flag=3;
    Serial.println("Record function undefined");
    break;
    }
    /** voice recognized */
    printVR(buf);
  }

  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);

  oax = ax+72;
  oay = ay-382;
  oaz = az-505;
  ogx = gx+99;
  ogy = gy-29;
  ogz = gz-50;

  vx = gx/200;
  vy = -gz/200;
  myData.moveX = vx;
  myData.moveY = vy;
  myData.flag = flag;

  memcpy(tx_buf, &myData, sizeof(myData));
  byte bufSize = sizeof(myData);
  Serial.println("movX\tmovY\tmovZ\toax\toay\toaz\togx\togy\togz\tvx\tvy:");
  Serial.print(myData.moveX, HEX);
  Serial.print("\t");
  Serial.print(myData.moveY, HEX);
  Serial.print("\t");
  Serial.print(myData.flag, HEX);
  Serial.print("\t");
  Serial.print(oax, DEC);
  Serial.print("\t");
  Serial.print(oay, DEC);
  Serial.print("\t");
  Serial.print(oaz, DEC);
  Serial.print("\t");
  Serial.print(ogx, DEC);
  Serial.print("\t");
  Serial.print(ogy, DEC);
  Serial.print("\t");
  Serial.print(ogz, DEC);
  Serial.print("\t");
  Serial.print(vx, HEX);
  Serial.print("\t");
  Serial.println(vy, HEX);

  rf_driver.printBuffer("Buffer values [vx, vy, status flag respectively]: ", tx_buf, bufSize); //each value is 16 bit. and serail monitor will show in 8 + 8 = 16 bit format
    rf_driver.send((uint8_t *)tx_buf, bufSize);
    //Serial.println();
    rf_driver.waitPacketSent();

    flag = 15;
    delay(1);

}

```

**Receiver.ino**

```
// Include RadioHead Amplitude Shift Keying Library
#include <RH_ASK.h>
// Include dependant SPI Library
#include <SPI.h>
#include <Mouse.h>
#include <Wire.h>
#include <I2Cdev.h>
#include <MPU6050.h>

#define leftRecord    (0)
#define rightRecord   (1)
#define doubleRecord  (2)
// Create Amplitude Shift Keying Object
RH_ASK rf_driver;

struct dataStruct{
  int moveX, moveY, flag;
  }myData;

void setup()
{
    // Initialize ASK Object
    Wire.begin();
    rf_driver.init();
    // Setup Serial Monitor
    Serial.begin(115200);
    if(!rf_driver.init()) Serial.println("Init failed");
}

void loop()
{
    // Set buffer to size of expected message
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);
    // Check if received packet is correct size
    if (rf_driver.recv(buf, &buflen))
    {
      int i;

      // Message with a good checksum received, dump it.
  rf_driver.printBuffer("Got:", buf, buflen);
        memcpy(&myData, buf, sizeof(myData));
        Serial.println("");

        Serial.print("moveX: ");
        Serial.print(myData.moveX);

        Serial.print("  moveY: ");
        Serial.print(myData.moveY);

        Serial.print("  Command Status: ");
        Serial.print(myData.flag);

      // Message received with valid checksum
      Serial.print(" Message Received: ");
      Serial.println((char*)buf);

      Mouse.move(myData.moveX, myData.moveY);

  if(myData.flag!=15){

  switch(myData.flag){

    case leftRecord:
    Mouse.click(MOUSE_LEFT);
    delay(10);
    break;

    case rightRecord:
    Mouse.click(MOUSE_RIGHT);
    delay(10);
    break;

    case doubleRecord:
    Mouse.click(MOUSE_LEFT);
    Mouse.click(MOUSE_LEFT);
    delay(10);
    break;
    default:
    break;
    }

    }
}
}

```

# Answer
In general, you want to stream some data. and the mouse lag is one of the main obstacles in data streams; lag. so many classic causes such as buffer over-runs and timing problems come to mind.

The cheap 433MHz modules are not a good choice in case of streams. they lack any robust protocol, ACKing and security.

I would do this things to make it better:

* use a better transmitter. maybe the cheap nRF24L01 ones.
* use a bigger buffer
* use two threads on the transmitter side. (e.g. use something like this, but two threads). one thread to collect data and writing it to a buffer, the next one to send data using nrf. furtunately, the nRF24 can send up to 32Bytes in one buffer transmission and the SPI interface is fast enough to fill it's buffer as quick as possible.
* if you have to, use another thread to calculate movements from MPU6050. so you don't have to read it continuouesly and send all that raw data to reciever. you may use some interpolation on the receiver side though.
> 1 votes

---
Tags: arduino-micro, wireless, rf, mouse
---


# Question
Title: Using signal strength feature of nRF24L01 module
This is a walkie-talkie project and this circuit really worked, voice can be transmitted from one nRF module to another nRF. Additionally, I want to observe how well the signal strength is, by lighting up an LED.

They talked about a test.RPD function here in order to do that. But it is said that we can't use this with nRF24L01, but can use only with nRF24L01P (I don't know what is the difference).

> Test whether a signal (carrier or otherwise) greater than or equal to -64dBm is present on the channel. Valid only on ***nRF24L01P*** (+) hardware. On ***nRF24L01***, use testCarrier(). Useful to check for interference on the current channel and channel hopping strategies. @return true if signal =\> -64dBm, false if not \*/

---

***Can't we use it in nRF24L01 really?***

If I cannot use this how can I use the `testCarrier` function to light up an LED (as Bright, Low and Off) as mentioned in the quote?

If I can use this, what changes in the code should be done? (The member TmrhProjects talked about it a little)

---

He also hints to this code.

```
bool rpd = radio.testRPD();

while (radio.available()) {
  signalStrength = rpd + 1;
  radio.read, etc...
}

```

**Should we write the above code in the `RF24.h` file or should we write it directly into the Arduino's main sketch?**

# Answer
> 1 votes
To get the signal strength just send 100 packets with no retries and see how many times the packet arrives.

```
radio.begin();
radio.setRetries(0,0); // by default nrf tries 15 times. Change to no retries to measure strength

char buffer[32];
int counter = 0;

for(int i=0; i<100; i++)
{
   int status = radio.send(buffer,32); // send 32 bytes of data. It does not matter what it is
   if(status)
       counter++;

   delay(1); // try again in 1 millisecond
}

// if counter > 80 signal strength is great
{

}

// else if counter > 60 signal strength is good
{

}

// etc

radio.setRetries(5,15); change back to its default when done.

```

For this code to work the receiver must be listening for data. Just listen for data on the receiver there is no need to validate the data.

---
Tags: arduino-uno, nrf24l01+
---


title: NodeMCU ESP8266

text:
# Question
Title: NodeMCU ESP8266
I am doing a project and using NodeMCU ESP8266. My project includes sensors for UART, I2C and 4 interrupts. I need to read the data from these sensors and get these data via microUSB in real time. While reading about NodeMCU ESP8266 there are so many points that came across and have certain questions.

1. Do flash uses GPIO6-11 all the time? Can we use any of these pins for our purpose? What if someone needs an SPI communication, as these pins are locked by flash.
2. Can I use GPIO-0 (flash pin) for my purpose, as after flashing the MCU the pin will get free.
3. Do CP2102 uses GPIO 1 and GPIO 3? Can I use these pins for my purpose? (Given I need the data via USB, which I guess comes through CP2102)
4. Can I receive the sensor data from SoftUART bus and get that data to my computer via USB?

I am confused from the articles given over internet. I request if anyone knows how these work, please explain.

Thank you

# Answer
> Do flash uses GPIO6-11 all the time? Can we use any of these pins for our purpose? What if someone needs an SPI communication, as these pins are locked by flash.

It is Quad SPI. The CS pins for this SPI interface are controlled by low level code. So you can't use this pins as GPIO and they have limited use as SPI too. If the flash access is set to normal SPI, the two pins io 9 and io 10 used for quad mode can be used as GPIO.

> Can I use GPIO-0 (flash pin) for my purpose, as after flashing the MCU the pin will get free.

You can use io 0 as GPIO. Only make sure it is HIGH at boot. The bootloader reads it at boot to determine if it should go to flashing mode. Other boot config pins are io 2, it must be HIGH at boot and io 15, which must be LOW at boot.

> Do CP2102 uses GPIO 1 and GPIO 3? Can I use these pins for my purpose? (Given I need the data via USB, which I guess comes through CP2102)

Pins io 1 and io 3 are wired to the USB chip and used for Serial. They can be used as io pins, if you don't need Serial communication over them. Serial in esp8266 Arduino can be swapped to different set of pins for use with a serial device. For output printing you can use Serial1 which has only TX. To relay this output to USB bridge io 2 (Serial1 TX) to io 4 (Serial TX wired to USB).

> Can I receive the sensor data from SoftUART bus and get that data to my computer via USB?

You can use SoftwareSerail or the trick mentioned above.

see NodeMCU pins
> 1 votes

---
Tags: nodemcu, pins, uart
---