text:
leonardo mouse readings
hi there im using arduino uno + usb host shield and i have taken the readings from the usb mouse in this line of code : x =  mi->dX;
and the x output is the speed of the mouse x coordinates
and i wanna make it thru an analog  reading from 0 to 1023 i should do a constrain and a map
then i send the data thru i2c comm and recieve them with a slave code and display them but the mouse on the screen is moving always when i give the mouse a left move the mouse moves always to left and when i gave the mouse roght it moves to the right always without stopping the cursor as if im giving it a speed direction + or - .
this is the master code :

#include<Wire.h>
#include <hidboot.h>
#include <usbhub.h>
#ifdef dobogusinclude
#include <spi4teensy3.h>
#include <SPI.h>
#endif
int x; // mouse x
int y; // mouse y
int y1;
int x1;
int l,r;
int x11,y11;
class MouseRptParser : public MouseReportParser
{
protected:
void OnMouseMove (MOUSEINFO *mi);
void OnLeftButtonUp (MOUSEINFO *mi);
void OnLeftButtonDown (MOUSEINFO *mi);
void OnRightButtonUp (MOUSEINFO *mi);
void OnRightButtonDown (MOUSEINFO *mi);
void OnMiddleButtonUp (MOUSEINFO *mi);
void OnMiddleButtonDown (MOUSEINFO *mi);
};
void MouseRptParser::OnMouseMove(MOUSEINFO *mi)
{
x =  mi->dX;
//x = constrain(x, 0, 1023);

Serial.println(x);

y =  mi->dY;
//y = constrain(y, 0, 1023);

Serial.println(y);

};
void MouseRptParser::OnLeftButtonUp (MOUSEINFO *mi)
{
Serial.println("L Butt Up");
l=0;
};
void MouseRptParser::OnLeftButtonDown (MOUSEINFO *mi)
{
Serial.println("L Butt Dn");
l=1;
};
void MouseRptParser::OnRightButtonUp (MOUSEINFO *mi)
{
Serial.println("R Butt Up");
r=0;
};
void MouseRptParser::OnRightButtonDown (MOUSEINFO *mi)
{
Serial.println("R Butt Dn");
r=1;
};
void MouseRptParser::OnMiddleButtonUp (MOUSEINFO *mi)
{
Serial.println("M Butt Up");
};
void MouseRptParser::OnMiddleButtonDown (MOUSEINFO *mi)
{
Serial.println("M Butt Dn");
x = 90;
y = 90;
};

USB Usb;
USBHub Hub(&Usb);
HIDBoot<USB_HID_PROTOCOL_MOUSE> HidMouse(&Usb);

uint32_t next_time;

MouseRptParser Prs;

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

Wire.begin();       //Begins I2C communication at pin (A4,A5)

Serial.begin(115200);
#if !defined(__MIPSEL__)
while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection
#endif
Serial.println("Start");

if (Usb.Init() == -1)
Serial.println("OSC did not start.");

delay( 200 );

next_time = millis() + 5000;

HidMouse.SetReportParser(0, &Prs);
}

void loop()
{
Usb.Task();
Wire.beginTransmission(8);
Wire.write(x);
Wire.write(y);
//Wire.write(l);
//Wire.write(r);

Wire.endTransmission();
delay(10);

}

and the output is speed direction of x and y :
0
0
0
1
1
2
3
4
5
66
66
78
99
102
113
22
3
0
and this is the slave code :
#include<Wire.h>
int x,y,l,r;
#include <Mouse.h>                                                                               // Analog output of vertical joystick pin

void setup() {
Serial.begin( 115200 ); // start serial for output
Wire.begin(8);
Wire.onReceive(receiveEvent);
Mouse.begin(); //Init mouse emulation
}

void receiveEvent( int bytes )
{

x = Wire.read();
y = Wire.read();
//l = Wire.read();
//r = Wire.read();
delay(10);
}

void loop() {

Mouse.move(x, y, 0); // move mouse on y axis
delay(10);
}

anyone could help please i think the problem is i should ask the current position  and the next postion and if it was not zero move the mouse otherwise if it is 0 do not move

Well, you are constantly sending the X and Y coordinates over and over and over again in loop()...

so what to do ?

Don't keep sending them? Only send them when you receive them from the mouse?

you really need to learn how to format your code properly ... it is not a problem when the code is short,  but when the code is more complicated, correct indentation is very important when trying to find missed braces

could you please show me how ?

look at the example code that is included in the Arduino IDE


text:
Trying to recover my TTL-Wifi
So I bought What I tought was a DOIT Wifi-TTL and after a few bad manipulations I wiped the firmware...
That means the leds are not turning on anymore and I see no activity on it when I connect to it with a USB-TTL...
The FCC ID on it says 2al3b-esp-m that seams to indicate a ESP-8285
(https://fccid.io/2AL3B-ESP-M/User-Manual/User-Manual-3413969)
I tried to flash it with Arduino ESP8285 samples and it flash right but I can't figure how / where I could retrieve the functionality that I had in the pas (login the the web server of it and interact with the TTL...
esptool.py v2.8
Serial port COM6
Connecting....
Chip is ESP8285
Features: WiFi, Embedded Flash
Crystal is 26MHz
MAC: 84:0d:8e:41:22:82
Uploading stub...
Running stub...
Stub running...
Configuring flash size...
Auto-detected Flash size: 1MB
Compressed 280400 bytes to 205882...
Wrote 280400 bytes (205882 compressed) at 0x00000000 in 18.3 seconds (effective 122.7 kbit/s)...
Hash of data verified.

Leaving...

https://github.com/SmartArduino/SZDOITWiKi/wiki/Drivers%2CFirmwares%2C-and-Tools

source: Stack Exchange

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

sort: votes


text:
How to use capactive touch on Adafruit board in Arduino mode?
I have a Trinket M0 which has three pins capable of capacitive touch, A0, A3, and A4. When using CircuitPython on these boards you can use the CapTouch Library. But as far as I can tell this does not exist for use in Arduino mode. Does anyone know how to get these pins to pick up capacitive touch? I've tried the Adafruit_FreeTouch library, but with zero documentation, it's not very user friendly. I thought I had it working with two pins, but whenever both pins detect capacity, the capacity is divided between them, so both pins report about the same capacity.
Any help would be greatly appreciated.
This question does seem like a duplicated of Built-in capacitive touch detection with SAMD21 development board (Arduino Zero Compatible) but there was never a solution.
Thanks!

have you tried the example code that is included with the Adafruit_FreeTouch library?

look at page 861 of the datasheet ... http://ww1.microchip.com/downloads/en/DeviceDoc/SAM_D21_DA1_Family_DataSheet_DS40001882F.pdf  ... the touch pins can be used discretely or in a matrix configuration

Example code for capacitive touch on Trinket M0.  Note: make sure to install the Adafruit FreeTouch library.
// touch - Capacitive touch demo using FreeTouch. Trinket M0 version.
// Note: the pin silkscreened 1 is Analog Pin 0.

#include "Adafruit_FreeTouch.h"

Adafruit_FreeTouch qt_1 = Adafruit_FreeTouch(A0, OVERSAMPLE_4, RESISTOR_50K, FREQ_MODE_NONE);

void setup()
{
  // Initialize A0 as a touch sensor
  if (! qt_1.begin())
    Serial.println("Failed to begin qt on pin A0");
}

void loop()
{
  int counter, result = 0;
  counter = millis();
  result = qt_1.measure();
  Serial.print("QT 1: "); Serial.print(result);
  Serial.print(" (");  Serial.print(millis() - counter); Serial.println(" ms)");
  Serial.println("\n*************************************");
  delay(200);
}

Information about the parameters for the constructor can be found at: https://forums.adafruit.com/viewtopic.php?f=8&p=610501  and are paraphrased below incase the link goes dead.
The parameters for the constructor are:
p - The input pin connected to the sensor.
t - How much to oversample the input.  One of the following:
OVERSAMPLE_1
OVERSAMPLE_2
OVERSAMPLE_4
OVERSAMPLE_8
OVERSAMPLE_16
OVERSAMPLE_32
OVERSAMPLE_64

Oversampling is a process of taking several measurements, finding the average, and reporting that instead of the actual readings. It's way of reducing noise, but also improves the accuracy of the measurement. The average value of noise is zero (if it wasn't, it would be a source of free energy), so the more readings you add together, the closer the noise error in the measurements approaches zero.
There's another side-effect of adding noise to measurements though: it dithers the sensor output around the real input value. If I have a window comparator that only measures "below 1v" and "above 2v", and feed it a signal at 1.1v plus a couple of volts of noise, I can expect to see about ten "below 1v" outputs for every one "above 2v" output. The noise pushes the signals above and below the thresholds, but vanishes if I take the average of a large enough sample. Statistically, getting a 10:1 improvement in resolution like that would take about 64 readings to make the noise error small enough to ignore.
Oversampling takes longer though, so there's always a tradeoff between how much you can do and how long the signal will remain stable.
r - The value of the resistor that will discharge the touch pad.  One of the following:
RESISTOR_0
RESISTOR_20K
RESISTOR_50K
RESISTOR_100K

f - Frequency mode.  One of the following:
FREQ_MODE_NONE
FREQ_MODE_HOP
FREQ_MODE_SPREAD
FREQ_MODE_SPREAD_MEDIAN

For systems that take repeated measurements, there's one kind of noise that doesn't average to zero: noise that occurs at the same frequency as the sampling rate. There are all sorts of videos that show the effect of a camera being in sync with the thing it's recording.. this one is especially nice:   https://www.youtube.com/watch?v=uENITui5_jU
For capacitive sensors, things like induced signal from fluorescent lights can create noise, and if the lamp frequency is just slightly off of your sampling frequency, the touch system will think it looks like a series of touches.
(If you have an oscilloscope, hold the tip of a probe between your fingers and put your hand within a foot or so of a fluorescent light.)
One way to prevent that is to change the sampling frequency. You can shift it up and down in a predictable pattern, hop from one frequency to another, or add some random jitter. Atmel's QTouch library supports all those options, but 'NONE' (fixed frequency readings) is the simplest.

Yes, FreeTouch is the answer.

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


text:
Circuit not working with 9 volt battery
I have made a simple circuit having an IR receiver and a Servo motor. Here is the diagram:

Red wire: power
Black wire: ground
Orange wire: digital signal
And here's the code:
#include <Servo.h>
#include <IRremote.h>
int receiver = 13;
IRrecv irrecv(receiver);
decode_results results;
Servo myServo;
int pos = 0;
void setup() {
  // put your setup code here, to run once:
  myServo.attach(9);
  Serial.begin(9600);
  irrecv.enableIRIn();
  myServo.write(0);
  delay(200);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (irrecv.decode(&results)){

    if (results.value== 0xC0000C){
      for (pos = 0; pos <= 90; pos += 10) {
        // in steps of 1 degree
        myServo.write(pos);
        delay(15);
      }
      for (pos = 90; pos >= 0; pos -= 10) {
        myServo.write(pos);
        delay(15);
      }
    }
  }
  irrecv.resume();
  delay(100);
}

It rotates the motor 90 degree and back when a button on a remote is clicked.
Here comes the problem: This is working perfectly when connected to my PC, but it doesn't when I connect it with my 9-volt (cuboid shaped) battery. The lights on the Arduino board still light up, but the circuit does nothing when I press the remote button.
I have also observed that the servo vibrates a little bit, but doesn't move.
Is this a problem in my circuit, or is it just that my battery power is low?

As many already have experienced, a 9V block can simply not deliver enough current for powering any significant load. You will have more luck with, for example, a 4- or 6- cell AA battery pack.

A 9V battery has both low peak current and low total power (low mAh rating). It is not a good choice for any circuit that draws more than ≈100 mA. (I pulled that number out of thin air, but it's probably a decent guess)
Build a battery pack from 6 AA alkaline cells instead. That will provide enough peak current. Or for much longer run-time, use 6 D sized cells.

you don't like the answer on the duplicate? or why you didn't vote for it?

I missed the duplicate vote. You're right, that would have been better than another answer.


text:
Problem on interfacing 3 flame sensors and servo to Arduino Fire Fighter
I had been trying to make Arduino Fire Fighter Robot but facing several problems in interfacing 3 flame sensors and servo together. When I upload the following code( Which I had posted at the end of my writing) my robot goes backward and detects flame at the front sensor and displays " Flame on Front" on 16x2 LCD display and the 5v  pump pumps out water and the red LED blinks. But I want that my robot will work in the following way- Initially, my robot will be at rest. There are 3 sensors attached at the front part of the robot. And there is a SG90 servo for rotating the water tank( in this tank there is a 5v pump motor and the pump motor will pump out water from this tank). When any one of the three flame sensors  will detect flame then the servo will rotate in that direction and when the front flame sensor detects fire , the servo will be in 90-degree angle and water will be pumped out. LCD will display the status of the flame sensors. But the robot is not working properly. I am not able to interface 3 flame sensors and servo together. My robot is not working according to my expectation as I had said before.
int pos = 0;
boolean fire = false;

#include <LiquidCrystal.h>
int Contrast=20;// for adjusting the brightness of the LCD , 20 is selected for the contrast of LCD
LiquidCrystal lcd(30,31,32,33,34,35);
int buzz= 38; //for led or buzzer
#define Left_S 9 // left sensor
#define Right_S 8     // right sensor
#define Forward_S 23  //forward sensor
#define LM1 52 //for pump motor
#define LM2 53 //for pump motor
#define IN1 5   //for motor
#define IN2 4  // for motor
#define IN3 3      //for motor
#define IN4 22     // for motor
//int flame_pin1 = HIGH ;
int LEDR= 36; // for danger signal
int LEDB=37;// for safe signal

void setup ( )  {
   analogWrite(6,Contrast);
     lcd.begin(16, 2);
      pinMode(Left_S, INPUT);
  pinMode(Left_S, INPUT);
  pinMode(Right_S, INPUT);
     pinMode (Forward_S,OUTPUT);
     pinMode (LEDB,OUTPUT);
 pinMode(LM1, OUTPUT);
 pinMode(LM2, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode( buzz,OUTPUT );
  pinMode(LEDR,OUTPUT);
  pinMode(LEDB, OUTPUT);
 // pinMode ( flame_sensor_pinM , INPUT );
  //Serial.begin ( 9600 );
   myservo.attach(25);
  myservo.write(90);
}
 void put_off_fire()
{
    delay (500);

    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);

   digitalWrite(LM1, HIGH);
   digitalWrite(LM2, LOW);
   delay(500);

    for (pos = 50; pos <= 130; pos += 1) {
    myservo.write(pos);
    delay(10);
  }
  for (pos = 130; pos >= 50; pos -= 1) {
    myservo.write(pos);
    delay(10);
  }

  digitalWrite(LM1,LOW);
  digitalWrite(LM2,LOW);
  myservo.write(90);

  fire=false;
}

void loop ( ){
   myservo.write(90); //Sweep_Servo();

    if (digitalRead(Left_S) ==1 && digitalRead(Right_S)==1 && digitalRead(Forward_S) ==1) //If Fire not detected all sensors are zero
    {
    //Do not move the robot
    lcd.setCursor(0, 1);
      lcd.print("No flame");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);
    digitalWrite(LEDR,LOW);
    digitalWrite(LEDB,HIGH);
    digitalWrite(buzz,LOW);
    }

    else if (digitalRead(Left_S) ==0) //If Fire is straight ahead
    {
    //Move the robot forward
    lcd.setCursor(0, 1);
      lcd.print("Flame on Left");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(LEDR,HIGH);
    digitalWrite(LEDB,LOW);
    digitalWrite(buzz,HIGH);
    fire = true;

    }
    else if (digitalRead(Forward_S) ==0) //If Fire is straight ahead
    {
    //Move the robot forward
    lcd.setCursor(0, 1);
      lcd.print("Flame on front");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN2, LOW);
    digitalWrite(LEDR,HIGH);
    digitalWrite(LEDB,LOW);
    digitalWrite(buzz,HIGH);
    fire = true;

    }

    else if (digitalRead(Right_S) ==0) //If Fire is to the right
    {
    //Move the robot right
    lcd.setCursor(0, 1);
      lcd.print("Flame on Right");
    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, LOW);
    digitalWrite(LEDR,HIGH);
    digitalWrite(LEDB,LOW);
    digitalWrite(buzz,HIGH);
    fire= true;
    }

     delay(300); //Slow down the speed of robot

     while (fire == true)
     {
      put_off_fire();
     }
}

your code is badly indented, so it is difficult to follow the program flow without reformatting

If you format your code correctly, the code becomes less cluttered and the problem becomes more visible.
Also, if you think about the if statements, there is no need to check for no fire for all three sensors at the same time. If none of the three sensors see fire, then the only possibility that is left, is no fire.
Another thing, you have no digitalWrite(IN1, LOW); and no digitalWrite(IN3, LOW); in your code. You could put digitalWrite(IN1, HIGH); and digitalWrite(IN3, HIGH); in setup()
Here is your code rewritten and formatted.
Couple of unnecessary duplications are tagged.
There is no reason to use while (fire == true) because put_off_fire() clears the fire flag
Also, for future programs, while (fire == true) is a redundant form because it is same as while (fire)
Have a really close look at the if statement blocks.
You used copy&paste when writing the code, but you forgot to make changes.
#include <LiquidCrystal.h>

LiquidCrystal lcd(30, 31, 32, 33, 34, 35);

#define Left_S       9                       // left    sensor
#define Right_S      8                       // right   sensor
#define Forward_S   23                       // forward sensor

#define LM1         52                       // for pump motor
#define LM2         53                       // for pump motor

#define IN1          5                       // for motor
#define IN2          4                       // for motor
#define IN3          3                       // for motor
#define IN4         22                       // for motor

//int flame_pin1 = HIGH ;

int LEDR     = 36;                           // for danger signal
int LEDB     = 37;                           // for safe signal
int buzz     = 38;                           // for led or buzzer
int pos      =  0;
int Contrast = 20;                           // for adjusting the brightness of the LCD , 20 is selected for the contrast of LCD

boolean fire = false;

void setup() {

    analogWrite(6, Contrast);

    lcd.begin(16, 2);

    pinMode( Left_S            , INPUT  );
    pinMode( Left_S            , INPUT  );
    pinMode( Right_S           , INPUT  );

    pinMode( Forward_S         , OUTPUT );
    pinMode( LEDB              , OUTPUT );   // xxxxxxxxxxxxx        duplicate

    pinMode( LM1               , OUTPUT );
    pinMode( LM2               , OUTPUT );

    pinMode( IN1               , OUTPUT );
    pinMode( IN2               , OUTPUT );
    pinMode( IN3               , OUTPUT );
    pinMode( IN4               , OUTPUT );

    pinMode( buzz              , OUTPUT );

    pinMode( LEDR              , OUTPUT );
    pinMode( LEDB              , OUTPUT );   // xxxxxxxxxxxxx        duplicate

//  pinMode( flame_sensor_pinM , INPUT  );

//  Serial.begin ( 9600 );

    myservo.attach(25);
    myservo.write(90);
}

void put_off_fire() {

    delay (500);

    digitalWrite(IN1, HIGH);
    digitalWrite(IN2, HIGH);
    digitalWrite(IN3, HIGH);
    digitalWrite(IN4, HIGH);

    digitalWrite(LM1, HIGH);
    digitalWrite(LM2, LOW );
    delay(500);

    for (pos = 50; pos <= 130; pos += 1) {
        myservo.write(pos);
        delay(10);
    }

    for (pos = 130; pos >= 50; pos -= 1) {
        myservo.write(pos);
        delay(10);
    }

    digitalWrite(LM1, LOW);
    digitalWrite(LM2, LOW);

    myservo.write(90);                       // xxxxxxxxxxxxx        duplicate

    fire = false;                            // xxxxxxxxxxxxx        not needed
}

void loop() {

    myservo.write(90);                       // xxxxxxxxxxxxx        duplicate
//  Sweep_Servo();

    lcd.setCursor(0, 1);

    fire = true;                             // preset the state (gets cleared when no fire is detected

    if (digitalRead(Left_S) == 0) {          // If Fire is straight ahead

        lcd.print("Flame on Left");

        digitalWrite(IN1 , HIGH);            // Move the robot forward
        digitalWrite(IN2 , LOW );
        digitalWrite(IN3 , HIGH);
        digitalWrite(IN2 , LOW );
    }

    else if (digitalRead(Forward_S) == 0) {  // If Fire is straight ahead

        lcd.print("Flame on front");

        digitalWrite(IN1 , HIGH);            // Move the robot forward
        digitalWrite(IN2 , LOW );
        digitalWrite(IN3 , HIGH);
        digitalWrite(IN2 , LOW );
    }

    else if (digitalRead(Right_S) == 0) {    // If Fire is to the right

        lcd.print("Flame on Right");

        digitalWrite(IN1 , HIGH);            // Move the robot right
        digitalWrite(IN2 , HIGH);
        digitalWrite(IN3 , HIGH);
        digitalWrite(IN4 , LOW );
    }

    else {                                   // fire was not detected by any of the sensors

        fire = false;

        lcd.print("No flame");

        digitalWrite(IN1 , HIGH);            // Do not move the robot
        digitalWrite(IN2 , HIGH);
        digitalWrite(IN3 , HIGH);
        digitalWrite(IN4 , HIGH);
    }

    delay(300);                              // Slow down the speed of robot

    if (fire) {

        digitalWrite(LEDR, HIGH);            // do fire lights
        digitalWrite(LEDB, LOW);
        digitalWrite(buzz, HIGH);

        put_off_fire();
    }

    else {

        digitalWrite(LEDR, LOW );            // do nofire lights
        digitalWrite(LEDB, HIGH);
        digitalWrite(buzz, LOW );

    }
}

Thanks for your suggestion. But the right motor starts to move when I upload the code to Arduino. And the servo is not also rotating. Suppose, the servo is at 90-degree angle. When the left sensor will detect fire then the servo needs to rotate at the left side. The servo's position remain at 90 degree position. Why?

Will I have to erase myservo.write(90) and fire= false; from Void put off fire()? Beside these two lines you wrote duplicate and not necessary

no, you do not have to delete duplicate lines ... i simply pointed out that you have duplicate code which indicates that you my want to review your code to make sure that you have not overlooked someting else

Thank u so much. But  right motor starts to rotate automatically when I upload the code why? Your suggestion will be highly appreciated.

test your motors ... write a sketch that runs one motor for one second, then reverses it, then the other motor

Ok. I will test my motors.

If I want to add MQ-5 ( for gas leakage detection) sensor in my robot then what's the way of adding it?


text:
Dragino lg01-p problem with serial monitor
i have a dragino lg01-p lora gateway to which i successfully communivate through lora with an arduino and i can program it through network as expected and seen in its manual with the demo client-server code. However, when i try to open the serial monitor on the side of the dragino, i get this:
Unable to connect: retrying (1)...
Unable to connect: retrying (2)...
Unable to connect: retrying (3)...
Unable to connect: retrying (4)...
Unable to connect: is the sketch using the bridge?
I need to have the serial communication cause i made a little app in C# which gets the data from a COM port. I also tried with Console instead of serial, but still didn't get any results back. This is the code, exactly as is in the examples no the manual
#include <SPI.h>
#include <RH_RF95.h>

// Singleton instance of the radio driver
RH_RF95 rf95;

int led = A2;
float frequency = 868.0;

void setup()
{
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  while (!Serial) ; // Wait for serial port to be available
  Serial.println("Start Sketch");
  if (!rf95.init())
    Serial.println("init failed");
  // Setup ISM frequency
  rf95.setFrequency(frequency);
  // Setup Power,dBm
  rf95.setTxPower(13);
  // Defaults BW Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
  Serial.print("Listening on frequency: ");
  Serial.println(frequency);
}

void loop()
{
  if (rf95.available())
  {
    // Should be a message for us now
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf95.recv(buf, &len))
    {
      digitalWrite(led, HIGH);
      RH_RF95::printBuffer("request: ", buf, len);
      Serial.print("got request: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);

      // Send a reply
      uint8_t data[] = "And hello back to you";
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Serial.println("Sent a reply");
      digitalWrite(led, LOW);
    }
    else
    {
      Serial.println("recv failed");
    }
  }
}

Found it so i will share my problem here to help someone else!
Apparently Bridge funcions work better for this device if you include Process.h rather than Bridge.h.


text:
How can I make my Arduino Uno press Space on my laptop keyboard?
So I wanna build something which, when it receives a remote signal, presses the spacebar on my laptop keyboard. I tried using the Keyboard.press() but it is available only for Leonardo. Is there any way I can use it in my Uno, without having to mess with the firmware?
If not, what else can I use to accomplish my goal?

https://github.com/NicoHood/Hoodloader

@Majenko Are you sure this has no dangers at all?

You can do that without burn a new bootloader via an interface application. The disadvantage is that you have to code a new application. You can do that with Java, C++, C#, ... You can send a message through serial and received it with your app. Tha's not the best way.

you could send a signal character over serial ... run a Processing sketch on the laptop that generates a keypress everytime the signal character is received

Control a servo that physically presses the spacebar...

On Windows you can use a serial to keyboard redirector like this one
It can start with windows, Im using it for a long time without any issues.

if you have some knowledge in Java or Python you can interface your Arduino board to PC, through Arduino's SerialPort.
When Arduino sends a byte, for example, 0xAB, your Java or Python script sends a fake key-press event.
I hope this can help. Good luck!

are you sure you can send a keypress event to any application from other application?


text:
esp32 e-paper driver not working
I am trying to setup waveshare 7.5 display (Waveshare_7_5) with esp32 e-paper driver using ESP32-e-Paper-Weather-Display
My code is here https://pastebin.com/raw/2zQDe9a9, have corresponding owm_credentials.h, installed GxEPD2 & U8g2_for_Adafruit_GFX
Code gets uploaded to esp32 driver board using Arduino IDE, but Getting following in serial monitor & no display on e-paper
Busy Timeout!
Busy Timeout!
Busy Timeout!
Busy Timeout!
Entering 1675-secs of sleep time
Awake for : 44.518-secs
Starting deep-sleep period...

What is wrong here ?

your question is about interfacing the e-paper display ... why does your program contain code relating to weather and to wifi? ... reduce the code to minimum required to display something on the e-paper display

Maybe I have the same problem on a ESP32 NodeMCU with a waveshare 1.54 inch display. Did you solve the problem?


text:
Junk values in EEPROM. while writing large values
Facing an issue while writing a large value (like 2000-5000) to EEPROM using EEPROM.put().
For example, While writing 2000 values to address 5 of EEPROM. Some junk values are written automatically to a nearby address (address 4, 6, 7...).
Note : Not trying to write an array of 2000 elements
Board Used : Arduino Uno (Atmega328P)
Q1 : What is the typical range of a each address by using EEPROM.put() . Like EEPROM.write() has range limit of 0-255.
Q2 : How to write large value EEPROM addresses without effecting the nearby address.

Are you writing the value 2000 or are you trying to write an arry of 2000 elements? Thats not clear in your question

@chrisl I am trying to write value 2000.

It depends on what type of variable you have.  If you have single byte variables like byte or char then it is one value to one address.  But if you have an int value like:
int x = 2000;

then try to store that in EEPROM that will take 2 bytes because an int is 2 bytes in size.  So if you write that to address 5 it will take 5 and 6 to write it.
If you write a long or a float, they are 4 bytes, so they will take 4 address slots in the EEPROM each.
If you just write EEPROM.put(5, 2000); then the 2000 gets seen as either int or long depending on how the code is written.  I don't remember.  But you certainly can't fit 2000 into a byte so it's going to have to take more than one.

The literal 2000 is always interpreted by the compiler as an int.

Yes the compiler does but I don’t know how the put function works. It could be like print where int ends up promoted to long in the function.

It's a template: it uses whatever type its argument has. Unlike print(), which is a collection of overloads.

Ok thanks.  Wasn’t able to look it up when I wrote the answer.  Wasn’t sure how it was handled but knew for sure we needed more than one byte.


text:
Uno went in washer and when I shake I hear something shaking around. What do I hear?
My friends Uno went in washer. I gave it a week to dry and when i plug it in, it works. But when I shake I hear something shaking around inside it. What do I hear shaking around?

There is no "inside" to have something shaking around, other than maybe the spaces in the DIP socket. Remove the DIP chip and see if there's something stuck in there.

Unless of course you have it in some form of case, in which case take it out of the case and case the joint. (English is a fun language, isn't it? ;) )

Ok, I will try your suggestion. (Yes English is.)

Just checked the socket. Nothing there. I shook it with the processor removed but I still hear something.

Maybe it’s the crystal? Idk.

Maybe it's in the power jack socket.

Possibly. At least it works.

My guess would be the pushy-part of the reset button. Try putting your finger on different part, then shake, and see if the sound is still there. I don't think it's something to worry about. As for the washing machine part; I wouldn't use that Arduino on something really important. Though it's probably fine.

it is probably the bits in the bit bucket ... lol

But the real question is does the magic smoke come out when you plug it in and turn it on.

Did you examine the board carefully no electronic part is broken or came out of PCB?

your question is not really about an arduino ... the same question could apply to a box of matches

It could be the USB port, barrel jack port, or most likely the pin header. The pin headers are a plastic shell with a two-point prong thing that goes in it. the pin could have desoldered when in the washer. check the pin headers. It might also be the inside of capacitors but that is highly unlikely.


text:
How to use Atmega328p-PU from an Uno, on a breadboard without a crystal
How do you use Atmega328p-PU from an Uno, on a breadboard without a crystal?

By changing the fuses to use the internal oscillator.

You could have the 328P's "fuses" set so it uses it's internal 8Mhz oscillator. In the Arduino IDE you can then select, for example, the Arduino Pro Mini 3.3V (which also runs at 8Mhz)

How do you set the fuses?

With a programmer or another Arduino acting as a programmer.

So all I have to do is bootload it as a Pro Mini 3.3v?

bootload it as a Pro Mini 3.3v? how do you do that ? There's an Upload Using Programmer, which requires that you use a Programmer.

Go online for a tutorial on how to do it.

If you buy your ATmega as supplied by Microchip, through one of the
large electronic parts resellers, it will come with its default fuse
configuration:

clock source: internal 8 MHz RC oscillator
clock prescaler enabled at ÷8, yielding a 1 MHz system clock
bootloader disabled

You could use it in this configuration, but you will probably want to
disable the prescaler. This can be done by changing the right fuse or,
alternatively, by some code running early in setup(). Note that, with
no bootloader, you will need an ISP programmer in order to load the
code. If you want the convenience of serial downloading (i.e. you would
use an FTDI cable rather than an ISP programmer), you will have to burn
the bootloader using an ISP programmer, and adjust the fuses to enable
it and set its size.
If you take the ATmega from an existing Uno board, or buy one
preconfigured with the bootloader, the fuses will be set differently:

clock source: external crystal
clock prescaler disabled
bootloader enabled and sized to 0.5 KiB

In this case you will have to change the clock source.
In any case, you would tell the IDE you are using an Arduino Fio, or a
Pro or Pro Mini with a 328P clocked at 8 MHz. And you will need an
ISP programmer to load either your program or the bootloader. You could
use an Arduino running the “Arduino as ISP” firmware for this.
Check the datasheet for the details on configuring the fuses. You can
also use one of the online fuse calculators, like this one or this
one.

Ok thanks for the help.

You can use another IC like the 555 timers as an external oscillator.


text:
Is it possible to send data from internet server to ESP8266 behind proxy or regular requests from ESP8266 are required?
It would be kind of push notification or something like that probably.
I can first connect to server and send it any data for "registration"...
I found many examples with websockets but all of them was about ESP8266 is like "server". That's not this case...

https://en.wikipedia.org/wiki/WebSocket

I found many examples with websockets but all of them was about ESP8266 is like "server" there. That's not this case...

So look for more examples where the ESP8266 is the client? They must be out there somewhere.

have you looked into using MQTT?

It seems evident that you don't want your ESP8266 running as a server of any kind. That's understandable given that server programs consume a fair amount of system resources (CPU, RAM, etc.) that are in short supply. That means you'll have to use your ESP8266 as a client and this means either

Polling - where the ESP8266 repeatedly connects to your "internet server" to explicitly ask for information at frequent intervals. Your internet server would have to be able to collect information in batches and hang onto it until your ESP8266 connects again to request the information.

Socket connections - where your ESP8266 maintains a consistent socket connection to your "internet server." Note that the HTTP protocol relies on socket connections, but clients open a socket connection, request a web page and its images, CSS, etc., then disconnects the socket. You can also use sockets at a more basic level as a bytestream. This programming can be tricky, but ESP8266 does have examples of TCP socket communication like WiFiClient and ethernet client.

Client approaches have a variety of headaches:

server has to hang on to information until the client comes back to retrieve it
you have to work up some kind of data structure to track which information has been handled and which work must still be done
latency issues -- i.e., what happens when there's a delay in processing information.

Server approaches also have challenges:

server programs can be tricky to write so that they keep running. a single exception or fatal error can crash the program
server programs are vulnerable to DDoS or other attacks, and can easily overwhelm a small device like ESP8266
firewall and networking issues -- depending on how this device connects to the internet, it may or may not have a consistent IP address where it can be found, the ISP that connects it may not allow incoming connections for the ports that it listens on, etc.


text:
Is it possible to implement old AVR library onto arduino (specifically, NodeMCU esp8266)
I am a Computer Engineering Undergrad, currently in a cryptography(computer security) course, and I was assigned to do projects about implementing µNaCl library onto Arduino. I currently own a nodemcu esp32 which serves as my device, and I have been searching for µNaCl libraries on the web, but the only thing I found was µNaCl library for AVR devices (based on the makefile of the library, i can see that it's designed for atmega128 and atmega2560). So my question is, is it possible to implement some library meant for AVR on my nodemcu? I mostly do my job with arduino libraries, and have never experimented with avr libraries on arduino, and especially considering my nodemcu is not using atmega-based architecture either, I kinda doubted it. And is the solution to my problem (if it's not possible to use avr based library on arduino) to go purchase a atmega128/atmega2560 and code on atmel studio?
Library: https://munacl.cryptojedi.org/atmega.shtml
Sorry for the long question, kinda desperate here.

That's hard to say without knowing the code, that you want to port. It should be possible, though it might mean rewriting the whole library. Please provide a link to the AVR library, that you are talking about.

the only link to the library i found was in the form of tarball packages so i guess it still needs to be 'make'-d on linux system, but here it goes https://munacl.cryptojedi.org/atmega.shtml
i'll edit the post, thanks @chrisl

nvm sorry it was dumb, there are C files in the zip so you can still look for it without actually making the file first

Why not give it a try? The tarball contains two optimized versions of the library (optimized for size and speed) with some functions implemented in AVR assembly, but also a version in pure C. It could be that it doesn't work on an ILP32 target, but it shouldn't be too hard to just try.

use the original version, not the AVR version

It just looks like normal C code, nothing too hardware (or OS) specific, therefore it shouldn't be too hard to port.  Maybe there's some difficult parts I didn't see, but I checked a few files.


text:
Power up Arduino using AC/DC Adapter
Wanna get your advice regarding powering up Arduino Uno using AC/DC Adapter to the barrel jack.
The first adapter I use couldn't work and the shop which I bought it from said the adapter was short circuit-ed.
Out of goodwill, she replace it for free and I tested it out again. The first few tries it worked perfectly fine but stopped working (suspected short-circuited again).
The adapter output is DV9V - 2A.
The circuit consists of 2 ultrasonic sensor and 1 buzzer.
I am quite sure the Arduino circuit does not draw more than 2A of current.
Any idea what's the issue? Thanks!
EDIT -
I've uploaded a photo of the schematic done using Tinkercad. I am using a different breadboard thus the configuration as shown.

As you suspect a short circuit, have you checked for that? Also: Are you sure, that the power supply is broken? Or is it the Arduino? The barrel jack is connected to a voltage regulator, which will go into emergency shutdown, if you draw more current through it, than supported, (for genuine Arduinos).  Cheap clones might get their voltage regulator destroyed. Please show your real circuit, so that we can check for a short circuit

You need to troubleshoot the system. 2 failed power supplies in a row seems suspicious. I would try to rule out a problem with your Arduino or with your circuit. Buy a multi-tester and measure the voltage out of your power supply, and the resistance of your circuit. You might want to add a 2A fuse to your power supply to protect it. (You'd need a male and a female barrel jack connector, a fuse holder, some wire, and a soldering iron.)

Switch-mode based DC adapters virtually have to have short circuit protection and OCP to pass UL certification (otherwise it would fail). Most smps driver chips have that built-in as well, so if it's a recently made adapter, that's probably not the issue.

Hi @chrisl I have uploaded a photo of the schematic. Can you help to take a look? The Arduino works perfectly fine because it is able to power up via USB. I am supplying a 2A into the Arduino which requires only 1A. I read on forum that supplying more current is fine

@DuncanC Hi, I've tested the adapter, it doesn't have any voltage output. So pretty sure the adapter is damaged. I'm trying to find out why the adapter is damaged

@dandavis Hi, yea the adapter should have. It's surprising that the adapter failed on a circuit with merely sensors and buzzer

My guess is that your project has a short circuit somewhere, and you are overloading your power supplies. Check the resistance on the power inputs to your project, and use ohms law to figure out how much current it would draw from the power supply at 9V


text:
Using Arduino to control a high voltage DC device
I am an amateur hobby electronics enthusiast , and given the situation , I too am trying to make a contactless hand Sanitizing system like everyone else. My project requires a 36V DC solenoid valve to be actuated through the arduino momentarily for the sanitizer to drop. Obviously I will be using a relay module to electrically isolate both the circuits. But I don't have a 36 V DC adapter . So what is the best way to power up the solenoid valve? Batteries are available to me right now? How do I calculate how many 9v batteries do I need ? How many AH would they require ? Would they get drained too fast?

36/9 = 4. AH defines the amount of time they will last at a certain current draw. You need to know the current draw and how long the solenoid will be powered for.

If you’re talking about the square looking 9V batteries then save yourself some money and don’t even buy them.  They’re not appropriate for driving motors.  They can’t produce the current you need.  Get AA batteries for this.  You need enough to make 36V.  It will be a lot.  You’d be better off getting a LiPO pack or just using a smaller servo.

My HP printers had 32V adapters, which will probably work too. Maybe you can salvage one from an old printer gathering dust somewhere in your house.

two old 18v ungrounded laptop supplies could be put in series to get 36v; those are safe and dirt-cheap.

For the record, 36V is hardly a "high voltage" DC device. The term high voltage usually implies something well over mains voltage. It makes me think of thousands, or even tens of thousands, of volts

Batteries are going to be annoying because they're run out and have to be recharged/replaced. A mains power supply would be easier to "set and forget.
I did a google search on "36V DC power supply" and found a 4A power supply from "Alitove" on Amazon for $22.99 US. That should be fine. (Assuming you are somewhere with 120VAC mains power. If you live somewhere with 240VAC mains power you would need a different unit, but since I found one, I would expect a google search in your region would find one for your area.)
I would suggest using a logic-level MOSFET transistor + flyback diode to switch your DC power. That's easier to do than a relay (That would require another power supply.)


text:
Consequences of messing with Timer 0
I'm following this tutorial to generate square waves using the timers of the attiny85, but I'm afraid this could mess with something else in the chip.
This is the relevant snippet:
// Set up Timer/Counter0 for 20kHz interrupt to output samples.
TCCR0A = 3<<WGM00;             // Fast PWM
TCCR0B = 1<<WGM02 | 2<<CS00;   // 1/8 prescale
TIMSK = 1<<OCIE0A;             // Enable compare match, disable overflow
OCR0A = 49;                    // Divide by 400

I understand that this might affect delay(), but as I'm using watchdog timer to send the attiny to sleep, I think this in this case it should not affect this specific function.
Are there another negative consequences of modifying this timer?

so, what is your question? ... the easiest thing would be to write a program that tests timer0 affect on sleep()

Timer 0 is usually used for millis() and delay().

I don't see how this could affect sleep. It does affect millis and delay, if you are using a "core" that implement that for the ATTiny85. I think most of them use the overflow interrupt (e.g ATTinyCore does). Your code disables that, so as long as you never call delay() or millis() there shouldn't be a problem.


text:
How to convert Unicode char to “Unicode HEX Position” in Arduino
How to convert Unicode char to "Unicode HEX Position" in Arduino or C
i will share a picture here :

for example in JavaScript you can do that with charCodeAt(); ! this function will return exactly the char-code and then you can convert it to hex!
for example in JavaScript i can do that like this to return exact table value
 var inpString = 'س';
    var myChar=0;
    var output = 0;
    myChar = inpString.charCodeAt(0);
    output = (ToHex((myChar&0xff00)>>8 )) + (ToHex( myChar&0xff ));

    function ToHex(i)
    {
        var sHex = "0123456789ABCDEF";
        var Out = "";
        Out = sHex.charAt(i&0xf);
        i>>=4;
        Out = sHex.charAt(i&0xf) + Out;
        return Out;
    }
 alert(output);

So how can i do that in Arduino ? its using to send unicode char in PDU mode in Arduino
i just need to convert unicode char like this -> 'س' to correct Unicode HEX Position that i shared in the picture above
for example 'س' is 0633 or 'A' is 0041 or 'ب' is 067E

Or simply console.log("س".charCodeAt(0).toString(16)).

please do not post at multiple locations ... https://stackoverflow.com/questions/62878287/how-to-convert-unicode-char-to-unicode-hex-position-in-arduino-or-c

Unlike JavaScript, C++ makes no difference between a character and its
code point. Thus, 'A', 0x41 and 65 are just different ways of
writing the same number.
Note, however, that the char type is intended to hold ASCII only. For
everything else, you may try using wide characters. For example, the
program
void setup() {
    Serial.begin(9600);
    wchar_t c = L'س';
    Serial.println(c, 16);
}

void loop() {}

outputs 633 on the serial port. Note the second argument to
Serial.println() which specifies base 16. Default is to print
numbers in decimal.
Beware that the representation of wide characters is implementation
defined, and the avr-libc doesn't provide support for manipulating them
or strings made with them. If you want to transmit them, you will also
have to decide for yourself how to break them down into a sequence of
bytes, as that's the only thing a serial port (or I2C, or SPI for that
matter) can transmit. UTF-8 is the most popular choice. I doubt wide
characters are popular in embedded systems at all.

its working, you are amazing thank you so much

so the difference to the sketch in my answer is the encoding of the source code versus the encoding of Serial Monitor.

@Juraj: The encoding of the source code is irrelevant to my answer as long as the dev environment is consistent (same encoding used by the editor and assumed by the compiler): the compiler initializes c with the code point of the character the editor shows between the quotes. It is basically equivalent to writing wchar_t c = 0x633, but in a way that hopefully makes more sense to the programmer. As soon as the program does I/O with non-ASCII characters, it will have to make a decision about the character encoding it is going to use.

This will read and print unicode characters from/to Serial Monitor and print their HEX codes. Please set the line ending in Serial Monitor to NL and confirm the entered character with Enter.
void setup() {
  Serial.begin(115200);
}

void loop() {
  if (Serial.available()) {
    char buff[4];
    int l = Serial.readBytesUntil('\n', buff, sizeof(buff) - 1);
    if (l > 0) {
      buff[l] = 0;
      Serial.println(buff);
      Serial.print(buff[0], HEX);
      if (l > 1) {
        Serial.print(buff[1], HEX);
      }
      Serial.println();
    }
  }
}

thank you for the answer , this code print -> D8B3 for -> 'س' , Not 0633 !
but its working correct for ascii character

If buff[0] is less than 16, you would have to zero pad. 2. This program assumes the serial monitor sends characters as UCS-2BE, which is not the case. Like almost everything nowadays, it uses UTF-8 for input and output.

@EdgarBonet, my sketch doesn't assume anything. it prints the hex values and I know it is UTF-8. and visible characters have codes > 0x10

The question is about printing the code point (not the code units!) of a character in hex. Your sketch prints the hex values of pairs of bytes, concatenated. The way they are concatenated embeds the implicit assumption that these bytes represent 16-bit numbers transmitted in big endian order. Considering these 16-bit numbers as equivalent to code points is only valid if the characters are transmitted as UCS-2.

A reliable way to output Unicode chars is to use Octal equivalents in the string you are printing.
e.g.
Serial.print("\342\204\211");

will output ℉ provided the receiver has  font for that unicode.
Using Non-ASCII chars in Arduino
has a .jar file that converts between Unicode chars, \u... strings and Octal
Hex \x.. is not used because C compilers can get confused if the next character after the two hex digits is 'a' to 'f'. Using octal avoids this problem. The GCC compiler used by Arduino also does not accept all unicode sequences such as \u0020


text:
I am using an accelerometer as an input and a stepper motor as an output and it will have these weird delays after about 30 sec
I have a stepper motor (kysan 1124090) turning CW and CCW based on the y direction of my accelerometer(MU6090). I am using an Arduino uno. It works great but after about 30 seconds there will be these pauses in the communication between the accelerometer and the stepper motor every 3-4 seconds. I can turn rotate the accelerometer and the stepper wont move for about half a second. I am wondering if its a storage issue, where after a while it has stock piled so much data that it needs that delay to keep it alive? When I verify the sketch it says I am only using 31% of the program storage space and 27% of dynamic memory. Maybe there is a way to get rid of all the data i dont need every time i run through my loop to get rid of this problem? I am attaching the code along with this. If anyone has any advice or things I could try, that would be awesome. Thanks.
#include <Wire.h>

#include "Kalman.h"

#define RESTRICT_PITCH

Kalman kalmanX;
Kalman kalmanY;

double accX, accY, accZ;
double gyroX, gyroY, gyroZ;
int16_t tempRaw;

double gyroXangle, gyroYangle;
double compAngleX, compAngleY;
double kalAngleX, kalAngleY;

uint32_t timer;
uint8_t i2cData[14]; // Buffer for I2C data

Stepper stepper2(200, 8, 10, 9, 11);
int cantidad = 1;

int previous = 0;
void setup() {

  stepper2.setSpeed(350);
  Serial.begin(115200);
  Wire.begin();
  TWBR = ((F_CPU /400000L) - 16) / 2; // Set I2C frequency to 400kHz

  i2cData[0] = 7;
  i2cData[1] = 0x00;
  i2cData[2] = 0x00;
  i2cData[3] = 0x00;
  while (i2cWrite(0x19, i2cData, 4, false));
  while (i2cWrite(0x6B, 0x01, true));

  while (i2cRead(0x75, i2cData, 1));
  if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
    Serial.print(F("Error reading sensor"));
    while (1);
  }

  delay(100);

  while (i2cRead(0x3B, i2cData, 6));
  accX = (i2cData[0] << 8) | i2cData[1];
  accY = (i2cData[2] << 8) | i2cData[3];
  accZ = (i2cData[4] << 8) | i2cData[5];

#ifdef RESTRICT_PITCH // Eq. 25 and 26
  double roll  = atan2(accY, accZ) * RAD_TO_DEG;
  double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
#else // Eq. 28 and 29
  double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
  double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
#endif

  kalmanX.setAngle(roll); // Set starting angle
  kalmanY.setAngle(pitch);
  gyroXangle = roll;
  gyroYangle = pitch;
  compAngleX = roll;
  compAngleY = pitch;

  timer = micros();
}

void loop() {

  while (i2cRead(0x3B, i2cData, 14));
  accX = ((i2cData[0] << 8) | i2cData[1]);
  accY = ((i2cData[2] << 8) | i2cData[3]);
  accZ = ((i2cData[4] << 8) | i2cData[5]);
  tempRaw = (i2cData[6] << 8) | i2cData[7];
  gyroX = (i2cData[8] << 8) | i2cData[9];
  gyroY = (i2cData[10] << 8) | i2cData[11];
  gyroZ = (i2cData[12] << 8) | i2cData[13];

  double dt = (double)(micros() - timer) / 1000000;
  timer = micros();

#ifdef RESTRICT_PITCH // Eq. 25 and 26
  double roll  = atan2(accY, accZ) * RAD_TO_DEG;
  double pitch = atan(-accX / sqrt(accY * accY + accZ * accZ)) * RAD_TO_DEG;
#else // Eq. 28 and 29
  double roll  = atan(accY / sqrt(accX * accX + accZ * accZ)) * RAD_TO_DEG;
  double pitch = atan2(-accX, accZ) * RAD_TO_DEG;
#endif

  double gyroXrate = gyroX / 131.0; // Convert to deg/s
  double gyroYrate = gyroY / 131.0; // Convert to deg/s

#ifdef RESTRICT_PITCH
//Serial.print("kalAngle is:"); Serial.print(kalAngleX);
  if ((roll < -90 && kalAngleX > 90) || (roll > 90 && kalAngleX < -90)) {

    kalmanX.setAngle(roll);
    compAngleX = roll;
    kalAngleX = roll;
    gyroXangle = roll;
  } else
    kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt);

  if (abs(kalAngleX) > 90)
    gyroYrate = -gyroYrate;
  kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);
#else

  if ((pitch < -90 && kalAngleY > 90) || (pitch > 90 && kalAngleY < -90)) {
    //Serial.print("pitch:"); Serial.println(pitch);
    kalmanY.setAngle(pitch);
    compAngleY = pitch;
    kalAngleY = pitch;
    gyroYangle = pitch;
  } else
    kalAngleY = kalmanY.getAngle(pitch, gyroYrate, dt);

  if (abs(kalAngleY) > 90)
    gyroXrate = -gyroXrate;
  kalAngleX = kalmanX.getAngle(roll, gyroXrate, dt);
#endif

  gyroXangle += gyroXrate * dt;
  gyroYangle += gyroYrate * dt;

  compAngleX = 0.93 * (compAngleX + gyroXrate * dt) + 0.07 * roll;
  compAngleY = 0.93 * (compAngleY + gyroYrate * dt) + 0.07 * pitch;

  if (gyroXangle < -180 || gyroXangle > 180)
    gyroXangle = kalAngleX;
  if (gyroYangle < -180 || gyroYangle > 180)
    gyroYangle = kalAngleY;

#if 0 // Set to 1 to activate
  /*Serial.print(accX); Serial.print("\t");
  Serial.print(accY); Serial.print("\t");
  Serial.print(accZ); Serial.print("\t");

  Serial.print(gyroX); Serial.print("\t");
  Serial.print(gyroY); Serial.print("\t");
  Serial.print(gyroZ); Serial.print("\t");

  Serial.print("\t");*/
#endif

 // Serial.print(kalAngleX); Serial.print("\t");

 // Serial.print("\t");

 // Serial.print(kalAngleY); Serial.print("\t");

#if 0
  //Serial.print("\t");

  //double temperature = (double)tempRaw / 340.0 + 36.53;
  //Serial.print(temperature); Serial.print("\t");
#endif

  //Serial.print("\r\n");

int valuex = kalAngleX;
//Serial.print("Valx:"); Serial.println(valuex);

stepper2.step(valuex - previous);

  previous = valuex;

}

the accelerometer does not communicate with the stepper motor ... the accelerometer communicates with the arduino ... the arduino controls the motor

right sorry, i was skipping the middle step. Do you have any ideas for the problem I am running into?

a lot of beginners read these posts ... some would think that a sensor is directly connected to the motor

isolate the area of failure ... try making the motor position independent of sensor readings .... maybe use millis() to determine motor position ... see if it still pauses

how would millis() work, doesnt that just have to do with keeping track of time?

i have not examined your code logic in detail ... maybe one of the if statements is getting an unexpected value .... put in some debugging Serial.print() statements

millis()/1000 would give you seconds ... use the value to move the stepper motor ... it should move every second ... basically use anything other that the sensor data to keep the motor moving ... if it does not stop as it did before, then that means it was previously commanded to stop

yeah that makes sense, okay i will try to make this work. Thank you

I couldn't figure out how to move the motor only based on only the millis(), is there any more help you can provide?


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

please put a space before the https:// in the URL ... without it, the link is not clickable

try the other example sketches

Hey @jsotola, I corrected the link. thanks for that catch. Also, I have tried the other demo sketches. The acceleration based demos work and even the StackingTest.ino demo works which doesn't use constant speed directly, but does individual stepping without acceleration and that works, but I still can't seem to figure out why the constant speed methods themselves do not work as expected.

I just realized that the Stacking test doesn't use the accelstepper library, so yeah, still at a loss :(

@jsotola, figured it out. See my answer below.

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


text:
esp32 board crashes
I try to connect sensors to esp32 board. when connecting a sensor, for example, DHT11, but it happens with others as well the board enter into a loop of boots with the following error
19:36:37.440 -> rst:0x10 (RTCWDT_RTC_RESET),boot:0x13(SPI_FAST_FLASH_BOOT)
19:36:37.440 -> flash read err, 1000
19:36:37.440 -> ets_main.c 371
19:36:37.772 -> ets Jun  8 2016 00:22:57

I tried to upload the board with led connected between the Vout and the GND and same thing happens.
any idea? where is the problem? blink catch with led connected between GND and a pin work fine.
I attach the board picture
many thanks,
Gilad

does the board work correctly when no sensors are connected?

"I tried to upload the board with led connected between the Vout and the GND", what is that for? Are you connecting an LED between Vcc and GND without a resistor?

@jsotola, Yes without sensors it works fine, can connect to wifi, upload data to firebase and blink led

@hcheung with a resistor. I thought to debug if the problem is with the sensor or the connection to Vout-GND. I connect the Vout to the CLK pin in the picture

I don't see a Vout on the board in the picture and the description of your setup is not very clear to me. Make sure you're not connecting pins carrying 5V directly to any pins of the ESP32 (which is a 3.3V device). Could you describe how you connect the sensor or show a schematic?

A flash read error might occur when you have the wrong partition scheme selected. Try with board type "ESP-dev-module" and a 4MB partition scheme.


text:
esp32 pico kit - actual clock speed vs crystal vs max_speed etc
I am trying to understand how the clock speed in the esp32 works.
I am running arduino ide 1.8.12 with 1.04 board definition - on a pico kit 4 module .
The device datasheet says it has a 40mhz crystal.
getCpuFrequencyMhz() reports 240mhz
But the following code is generating 1sec interrupts with 80mhz as a base i.e., as if the clock speed is 80mhz.
If I explicitly set the clock speed to 80 mhz then getCpufrequency correctly reports it as 80, and the code still keeps generating 1sec interrupts (as it should at 80). If I set the clock to 40mhz then I finally see interrupts at 2 secs as would be expected. What is the deal with the 240 report for what is actually 80 and where is 80 coming from on a supposedly 40 mhz part?
I am sure that the explanation is somewhere in expressif's docs, but I have been unable to glean it. Can anyone quickly explain what is going on or point me to some resource that explains this particular circumstance?
---------------
Sample output
getCpuFrequencyMhz() = 240
interrupts so far = 1 - : - mills() = 1018
interrupts so far = 2 - : - mills() = 2018
interrupts so far = 3 - : - mills() = 3018
interrupts so far = 4 - : - mills() = 4018
interrupts so far = 5 - : - mills() = 5018

----------------Sample code
#include "esp32-hal-cpu.h"

volatile int interruptCounter;
int totalInterruptCounter;

hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  interruptCounter++;
  portEXIT_CRITICAL_ISR(&timerMux);

}

void setup() {

  Serial.begin(115200);

  Serial.printf("getCpuFrequencyMhz() = %d\n",getCpuFrequencyMhz()); //Get CPU clock

  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 1000000, true);
  timerAlarmEnable(timer);

}

void loop() {

  if (interruptCounter > 0) {

    portENTER_CRITICAL(&timerMux);
    interruptCounter--;
    portEXIT_CRITICAL(&timerMux);

    totalInterruptCounter++;

    Serial.printf("interrupts so far = %d - : - mills() = %d \n", totalInterruptCounter, millis());

  }
}

look at the link in section 3.3.3 of this ... https://www.espressif.com/sites/default/files/documentation/esp32_datasheet_en.pdf ... section 4.2 in that link

@jsotola Thanks that is definitely helpful. I am not sure yet if it explains everything, but it does appear to have some of the key missing elements.


text:
SPI communications with an 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: 1.
This is my code, pretty straight forward (although this is my first time working with SPI). I am 100% sure the wiring is correct.
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 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);
}

not the problem, but SPI.begin() configures the SPI pins so your list of pin numbers and pinmode settings are unnecessary for MOSI, MISO and CLK

the sensor is not 5V tolerant. how did you wire it?

@hcheung not sure where am I using the Arduino board as a slave here?

@Juraj SPI.beingTransaction(settings) uses my pin numbers and settings, downstream from SPI.begin(), correct?

@Juraj Wiring graphic: https://i.imgur.com/ShAVLqc.jpg

hardware SPI pins on Uno are not selectable. I don't see level conversion in the picture? is the device SPI master?

If I read the section 4.4.1 of the datasheet correctly, you send a write command 0xE9 follow by a TSS command to tell the device what you want to retrieve, and if the return value is either 0x00 or 0x06, you send a 0x69 to read the data. I don't see your code is doing that. In fact, I have hard time to find where you get those commands that you used from the data sheet.


text:
Different Counter Reading on Serial Monitor Vs .96" OLED I2C
I've cobbled some code together from reading multiple sources on the web.  Makeatronics in particular to help me get this rotary encoder code together (shout out to them).  I'm pretty close to the end, but now trying to port it over the OLED display.  Not sure what the issue is, but it doesn't miss counter steps when read on the serial monitor, but does when ported to the OLED.
I increased the clock speed to 400Khz using Wire.setClock as I saw that suggested in some other places for I2C comms.
1.) Any thoughts on how I can improve the code or hardware to get this to read without missing steps?
Hardware:

Nano (USB Powered)
White .96" OLED I2C SSD1306
HW-040 Rotary Encoder

Libraries:

Arduino WIRE
Adafruit SSD1306 Library

The Serial Monitor Code:

#define PinCLK 2
#define PinDT 3

volatile boolean turnDetected = false;
void rotarydetect() {
  turnDetected = true;
}

void setup() {
  attachInterrupt (digitalPinToInterrupt(2), rotarydetect, CHANGE);
  pinMode(PinCLK, INPUT_PULLUP);
  pinMode(PinDT, INPUT_PULLUP);
  Serial.begin(2000000);
}

void loop() {
  if(turnDetected) {
    turnDetected = false;

    static uint8_t enc_val = 0;
    static int16_t enc_count = 0;
    static int8_t lookup_table[] = {0,1,0,-1,-1,0,1,0,0,1,0,-1,-1,0,1,0};
    static long lastTimeToDebounce = 0;
    static int debounceTime = 1;
    static int enc_counter = 0;

    if((millis() - lastTimeToDebounce) > debounceTime) {

    enc_val <<= 2;
    enc_val = enc_val | ((PIND & 0b1100) >> 2);
    enc_counter = enc_counter + lookup_table[enc_val & 0b1111];

    Serial.print("Counter: ");
    Serial.println(enc_counter);
    Serial.println("");
    }
    lastTimeToDebounce = millis();
  }
}

And the OLED Code:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>

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

#define PinCLK 2
#define PinDT 3

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

volatile boolean rotated = false;

void rotarydetect() {
  rotated = true;
}

void setup() {
  Wire.begin();
  Wire.setClock(400000);
  attachInterrupt (digitalPinToInterrupt(2), rotarydetect, CHANGE);
  pinMode(PinCLK, INPUT_PULLUP);
  pinMode(PinDT, INPUT_PULLUP);

  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.setTextSize(1);
  display.setTextColor(SSD1306_WHITE);
}

void loop() {
  if(rotated) {
    rotated = false;

    static uint8_t enc_val = 0;
    static int16_t enc_count = 0;
    static int8_t lookup_table[] = {0,1,0,-1,-1,0,1,0,0,1,0,-1,-1,0,1,0};
    static long lastTimeToDebounce = 0;
    static int debounceTime = 3;
    static int enc_counter = 0;

    if((millis() - lastTimeToDebounce) > debounceTime) {

    enc_val <<= 2;
    enc_val = enc_val | ((PIND & 0b1100) >> 2);
    enc_counter = enc_counter + lookup_table[enc_val & 0b1111];
    display.setCursor(0,0);
    display.clearDisplay();
    display.print("Counter: ");
    display.println(enc_counter);
    display.println("");
    display.display();

    }
    lastTimeToDebounce = millis();
  }
}

I also tried the LCD_1602 screen (still through the I2C module board), and more or less it has the same results.  I also switched the code from the ISR to trigger the code loop, to a polling loop that detects when the CLK pin changes state with the LCD 1602 screen.  Same array with bit shifting as above for state detection.  Same results.  I also removed the very low debouncing code altogether with the Wire.setClock(400000) same results.
Seems like this may be a I2C limitation for communication?

There is a lot more overhead in displaying a value than there is in serial output, so it may well be a combination of I2C speed and that overhead. The nano is a pretty slow processor. One thing you could do to compare them would be to use micros() to measure the length of time it takes to output the count in each case; then you'd get an estimate of how much slower the display is vs the serial port. Just store the current micros() value before the Serial or display calls, then output the difference between it and the current value to measure the microseconds output took.

Move the code related to screen clear(i.e.display.setCursor(0,0); display.clearDisplay(); display.print("Counter: ");) to setup(), you don't need to clean the screen on every loop. All you need is to set the cursor to where you want  the enc_counter to be displayed on the screen and display.println(enc_counter);.

@romkey Yeah, ~3000 microseconds for Serial.print versus ~37000 microseconds for the the I2C. I have a .96 OLED SPI that I will test and let you guys know the results.

@hcheung - The previous microsecond test I just discussed was done with the code update you suggested so that the display isn't clearing each loop.  It still lagged and missed steps unfortunately.  I'll chalk this one up to a communication speed issue.


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

Your post title is how to generate the graph, but what you actually described  and asking is how to get ride the unnecessary garbage from the Putty.

The time stamps you see in the serial monitor are generated by the serial monitor.

You could write a visualization with processing

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.

I  used the serial plotter. I get a plot of both temperature (as a blue line) and humidity (as a red line). However, I can't still get time to display on the x-axis. How do I accomplish this?

I believe the x-axis is the number of samples.  If you send your plot values on a particular time cadence, the x-axis should then correspond to time.


text:
Problem with interfacing Cirus OS1 oxygen sensor with Arduio Uno
I am trying to interface Arduino UNO with Cirus OS1 oxygen sensor but not able to get the expected output. The expected voltage output of OS1 sensor is 9-13mV and the oxygen % is expected to be in the range 19-21 %.
I am using the code :
void setup()

{

     Serial.begin(9600);
     analogReference(INTERNAL);
}

void loop()
{

     const float A_REF = 1.1e3;
     const float Sensor_Cal = 1 / 0.6;
     int sensorValue = analogRead(A0);
     float voltage = sensorValue *(A_REF / 1024);
     float oxygen = voltage * Sensor_Cal;
     Serial.print(" Voltage in mV : ");
     Serial.print(voltage);
     Serial.print("  ");
     Serial.print(" Oxygen level in % : ");
     Serial.println(oxygen);
     delay(1000);
}

However, I am getting an output :

I am using Cirus OS1 oxygen sensor - https://www.biometriccables.in/collections/oxygen-sensors/products/oxygen-sensor-os1
Expected voltage range - 9mV to 13mV
Expected oxygen % - 19 to 21 %
Have tried using LM324N opamp, but it's still not giving expected output. Kindly help or suggestions are welcome.


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

Your WebSocket server listens on port 81, whereas your client connects to 9000–9003. Are you sure the HTML you posted matches the sketch just above it? Please, make sure the elements of your question are consistent with one another.

Ohh, I'm really sorry for that, actually I made several versions  of this project, and previously I did with, one websocket port, and actually I mistakenly pasted it from that project. I'm just making it right.

now you can check!

Having 4 servers isn't neccessary. Does the latency happen from time to time and does recover or does the latency remain high? I currently have a similar issue with the WebsocketsClient from that repo

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.

No, i just used SoftwareSerial for the SBUS between NodeMCU and Nano, that has nothing to do with websocket, and without that, it still gives the same problem.


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

An atmega328p "with bootloader" might have something different than the current optiboot preloaded. Choose a "Nano with old bootloader" as your arduino target.

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.