text:
AD8232 - Measuring heart rate only if USB connector is touched. Grounding issue?
TL;DR
I can read out my heart rate but I have to physically touch GND of the Arduino or else the signal is just noise.
Description
So I've started to play around with an Arduino and wanted to try out a heartrate sensor module (AD8232).
The following is the code I am using for this:
const int CONNECTED_LED = 13;

const int LO_MINUS = 10;
const int LO_PLUS = 11;

bool disconnected = true;

enum State {
  CONNECTED,
  DISCONNECTED,
  LO_MINUS_DISCONNECTED,
  LO_PLUS_DISCONNECTED
};

enum State currentState = DISCONNECTED;

void setup() {
  Serial.begin(9600);
  pinMode(LO_MINUS, INPUT); // Setup for leads off detection LO +
  pinMode(LO_PLUS, INPUT); // Setup for leads off detection LO -
}

void loop() {
  State nextState = getState();

  if (nextState != currentState) {
    // Store the current state
    currentState = nextState;
    switch (nextState) {
      case DISCONNECTED:
        break;
      case LO_MINUS_DISCONNECTED:
        break;
      case LO_PLUS_DISCONNECTED:
        break;
    }
  }

  if (currentState == CONNECTED) {
    digitalWrite(CONNECTED_LED, HIGH);
    Serial.println(analogRead(A0));
  } else {
    digitalWrite(CONNECTED_LED, LOW);
    // Serial.println(-1);
  }

  delay(1);
}

State getState() {
  if (digitalRead(LO_MINUS) == 1 && digitalRead(LO_PLUS) == 1) {
    return DISCONNECTED;
  } else if (digitalRead(LO_PLUS) == 1) {
    return LO_PLUS_DISCONNECTED;
  } else if (digitalRead(LO_MINUS) == 1) {
    return LO_MINUS_DISCONNECTED;
  }
  return CONNECTED;
}

This is how I am connecting the boards (I double checked already twice)
AD8232  | Arduino UNO R3
------------------------
GND     |  GND
3.3v    |  3.3V
OUTPUT  |  A0
LD-     |  ~10
LD+     |  ~11
SDN     |  <not used>

I've followed this diagram for connecting the electrodes:

However, the result is a random signal unless I am touching the USB-connector or GND of the Arduino.
Below you can see the random signal and the moment I touched the connector. I noticed this by accident after hitting the reset button after wondering why on earth I only get this random signal:

So.. what's going on here? I have all three electrodes connected.
I've even tried to different modules (I bought the AD8232 two times) but I see the same issues with both modules.
If I touch something else e.g. a radiator (heater) then the signal becomes another kind of random. It only works touching the connector.
Since this appears like a grounding issue I checked for continuity from the GND pin of the AR8232 to the USB connector and continuity is given.
I'm not expert enough (yet) to see the problem. Anybody?

The Sparkfun tutorial https://learn.sparkfun.com/tutorials/ad8232-heart-rate-monitor-hookup-guide/all  links to a sketch which reads also pins 10 and 11 (to detect a lead placement/connection problem) which you are ignoring.

@6v6gt I have updated my code to the actual thing I am using. Both electrodes appear to be connected (only occasionally I see a disconnect) but most of the time I can read values from A0. It's just that it does not resemple a heartbeat ECG at all.

You are powering the module with 3.3 volts ? If you are using a 5 volt Uno, it will see a maximum analog reading of about 675  for peaks in a 3.3 volt signal. There does seem to be some clipping in the top range of the signal.

Yes, according to those tutorials and the module, the power should be 3.3V. Nothing I see makes sense here. I've tried some sanity checks because I started thinking maybe I killed the Atmega accidentally but basic "LED blinking" is still working fine. I've absolutely no idea what this thing wants from me XD

Interestingly, your serial plotter shows a range of 50 units (samples?) on the X axis. That would be about 50ms which, for a heart beat in the normal range, is clearly not enough. The Serial plotter with IDE version 1.8.19 shows a range of 500 units on the X axis which appears to be the same as the Sparkfun tutorial screen shots. Try increasing the delay until the full scale is 3 or 4 normal heart beats or export the results say to Excel and plot there.

@6v6gt I've just updated the code and the plot. It's weird.. I've tried several delays now. A heartbeat appears to take around a secod (according to Google) so I've tried 1, 10, 25, 50 and 100 milliseconds using delay() but I always get chaotic results. As you can see above, the plot is not continuos as if the electrodes weren't connected at times. It's very jittery and I have no idea why. If I press the sensors on the skin the average jumps around but that's about it. Not sure where the problem is..

Your code has multiple Serial.println() statements which could be causing the gaps. You should have only one (new line character) after printing the data line ( consisting of the 0, the 750 and the analog value). If there is a bad result, just print say 10 instead of the analog value so only numerical data is sent to the plotter. Maybe add a fourth plot that toggles between say 700 and 740 every 100ms.

Tried that. The values jump around between 300 and 700 -I can't comprehend what's going on. Either it's completely broken somehow or the plotter is not working as intended. I do set the output pin 13 to HIGH in order to see if I am connected or not - this light is flickering so it still kind of appears as if the connections aren't not working properly. I've tested everything for continuity with the multimeter so I don't think there's an issue - except the pads maybe but I didn't use them before. The other day I tested a smoke sensor which worked just fine ..

You'll see that the limited number of sample that the IDE V2.x.x Serial plotter allows (by default) has got some criticism. Also there is also an apparent work around at the end of this thread: https://github.com/arduino/arduino-ide/issues/803. One of your problems is that if you increase the delay between samples enough to be display about 2 seconds of data (say 40ms), if only 50 samples are allowed, you may miss the interesting peaks.

I was about to post the same link as I've extended the number of samples to 5k now but the result is just pure garbage..  I just don't get what the hell is going on here...

@6v6gt Okay so.. I kind of got it working.. it only works if I touch the USB connector of the Arduino. Only discovered this by accident. Any idea what the problem is? It should work without that, shouldnt it?

Read through the reviews here and see if anything jumps out. The reviews titled "Great But Bad Pinout", "Poor Signal-to-Noise (SNR) ratio", "It actually works! for hobby purposes" all seem to contain something that may be relevant to your problem.

@timemage hm, not sure. It appears that I myself need to be grounded because after touching GND the signal is "okay". Yeah it's very noisy but you could compute the heart rate with that. My problem is that I don't understand why I have to be grounded in order to get a signal. I thought this measures voltage differences between two points given a reference point.

Yes, I saw that. I'm saying that touching the USB shield could be having any number of effects related to the things mentioned in those reviews. I'm not able to test what happens if you run it on a battery or if you change the connections to the jack, or if you filter out your mains frequency. But you are.

I'm running it via the USB cable but I can try switching it to a battery. It's interesting because if I touch the radiator, then it will read a disconnect. If I touch the GND of the Arduino, it "works". Anything else is just random noise. Weird. ^^

Are you using electrodes that Sparkfun made or did you wire them yourself?

I am using the ones that came with the module itself.

One of your three ECG leads is equivalent to (human)body ground, and it's not making contact. I spent too long making this image to explain it, which should help you a lot more than it will me.  I mean, I don't have the board in my hands, so I cannot see which lead goes to which pin.  You can, easily, with a multimeter testing for continuity between the:
RIGHT ARM,
RIGHT LEG,
LEFT ARM (RA, RL, LA) solder spots, and the tip, ring, barrel of the jack.
Something to keep in mind though is the headphone jack switch.  When the plug is physically inserted, this switch opens.  Again, I'm not there to guide your multimeter, so this image is the best I can do for you.  One of your leads is going to be a grounding lead. It may be the "black" one, it may be the (traditionally) "RL" one, it may be another one, i can't tell.
When you touch USB ground you are effectively replacing the body contact of the missing ground lead. I made these images for you to better understand it.  You should be able to fault find this in a few minutes via you MM and continuity testing.

I've tested all three electrodes and I can detect continuity for each of them on the barrel of the jack. I don't think that's the problem. Like mentioned, I have two boards and two sets of electrodes and the issue is the same in both cases. However, is there any chance that it could be the power source? Right now I am powering it via USB cable from my PC. there might be a chance that I have to isolate the sensor and use a battery instead?

I can detect continuity for each of them on the barrel of the jack
erm... so....  all three electrodes are shorted to the barrel when plugged into the jack?  If that's the case you need to re-read what I wrote to you.

No, what I meant was RL, LA and RA are connected. The cables are fine.

I can't be any more helpful to you. The information you need is presented, and I cannot possibly be there to do it for you.

Make sure you unplug the PC charger. I unplugged it and the module then worked fine for me as shown in this video Here


text:
How do I use two ultrasonic sensors to control a 5 V motor?
I've hooked up two ultrasonic sensors to my breadboard and I also got a 5 V motor installed. I also got the diode installed and the usual set up. I can easily control the motor with one sensor.
I want the motor to run at let's say 100 once I start it up:

The first sensor should be used to slowly slow down the motor when an object is placed in front of it
The second sensor should be used to slowly speed up the motor when an object is placed in front of it

I do not want the speed to return to 100 once the object is removed. It should remain at the same speed according to which sensor was used.
Tell me if I have to clarify anything in the comments.
Code
int motorPin = 9;
int trigPin = 13;
int echoPin = 12;
int trigPin2 = 5;
int echoPin2 = 4;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  int duration, distance;
  digitalWrite (trigPin, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin, LOW);
  duration = pulseIn (echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance < 20) {  // Distance from sensor
    analogWrite (motorPin, 50);
  } else {
    int duration, distance;
    digitalWrite (trigPin2, HIGH);
    delayMicroseconds (1000);
    digitalWrite (trigPin2, LOW);
    duration = pulseIn (echoPin2, HIGH);
    distance = (duration/2) / 29.1;
    if (distance > 20) {  // Distance from sensor
      analogWrite (motorPin, 150);
    }
    if  (distance > 20) {  // Distance from sensor
      Serial.println("Out of range");
    } else {
      Serial.print(distance);
     Serial.println(" cm");
    }
    delay(500);
  }
}

Is "100" half speed?

uhm the max is 225, so I assume that the half speed should be around 112. but yeah, in my concept it's half speed

What do you want to happen if the two objects were both kept at the same time infront and at the back of the robot?
This problem can be solved if you wrote down all possible combinations which is as far as i see it 4 combinations.

Well what I want when two objects were both kept at the same time is that the speed turns to normal (default) as in 100

Is there anyway to the same thing but with a raspberry Pi and a PWM extension/driver HAT from adafruit?
Same ultrasonic sensor and a single motor. What I'm trying to do is increase the speed of the motor when there's something close to the motor (also reverse direction) and keep the motor running forward as normal if the object is far away

This is very simple using the map() instruction. Here's the code you would use (feel free to modify values:
int speed = 112 + map(distance, 0, 20, 0, 112) - map(distance2, 0, 20, 0, 112);

So if both sensors gave equal values, they would offset each other. To make it still work if an object is removed, you could just use the last distance/distance_2 value and update the other.

One issue with this approach is, if the line of transformation of the object is not perpendicular to the line of the pings, the value will go:

10 → 11 → 12 → 13 → 14 → 15 → 16 → 17 → 18 → 19 → 20 → [Out of range]

I've added some pretty animations to show you what I mean:
Perpendicular:

Collinear:

As I understand, this is what you want:
int motorPin = 9;
int trigPin = 13;
int echoPin = 12;
int trigPin2 = 5;
int echoPin2 = 4;
int postdist = 112;
int postdist2 = 112;

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(trigPin2, OUTPUT);
  pinMode(echoPin2, INPUT);
  pinMode(motorPin, OUTPUT);
}

void loop() {
  //First Read
  int duration, distance;
  digitalWrite (trigPin, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin, LOW);
  duration = pulseIn (echoPin, HIGH);
  distance = (duration/2) / 29.1;
  int ltol = postdist - 5;
  int htol = postdist + 5;
  if (distance > 20 || !(distance > ltol && distance < htol)) {  // Distance from sensor
    Serial.println("Out of range");
    distance = postdist;
  }
  //Second Read
  int duration2, distance2;
  digitalWrite (trigPin2, HIGH);
  delayMicroseconds (1000);
  digitalWrite (trigPin2, LOW);
  duration2 = pulseIn (echoPin2, HIGH);
  distance2 = (duration2/2) / 29.1;
  int ltol2 = postdist2 - 5;
  int htol2 = postdist2 + 5;
  if (distance2 > 20 || !(distance2 > ltol2 && distance2 < htol2)) {  // Distance from sensor
    Serial.println("Out of range");
    distance2 = postdist2;
  }
  //Math:
  Serial.print("Distances-1: ");
  Serial.print(distance);
  Serial.print(" cm 2: ");
  Serial.print("Distances-1: ");
  Serial.print(distance2);
  Serial.println(" cm");
  postdist = distance;
  postdist2 = distance2;
  int speed = 112 + map(distance, 0, 20, 0, 112) - map(distance2, 0, 20, 0, 112);
  if(speed < 60) {speed = 60;} //Modify 60 to meet your needs for minimum threshold
  analogWrite (motorPin, speed);
  Serial.print("Motor Speed: ");
  Serial.println(speed);
  delay(500);
}

Changelog: forgot to edit postdist/postdist2 at end of cycle, added minimum threshold, prevent very small changes in voltage to keep voltage stable and prevent noise.

Thank you for the help. Whenever I try to do it according to what you've posted above, the motor kinda acts weird. Weird as in, it just stops working all of a sudden and then starts working again.

Can you confirm that you use a transistor to drive your motor (don't connect it directly to an Arduino pin)? Also, you should use a flyback diode in parallel with it.

Yes I am using a transistor and a diode.

Chatroom created

source: Stack Exchange

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

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

sort: votes


text:
How to make better looking webpages on an Arduino webserver?
I have a Teensy 4.1 with ethernet, but I have other networked MCUs like a D1 mini, various ESP8266s and Arduino ethernet shields.
My question is: how I can make better looking web pages on these devices, where having a filesystem is limited by memory, or which lack a filesystem.
Specifically, I would like to add SVG images; I'm interested in how to make things like background images. I understand HTML/CSS, and I can code in C, get my data, whatever, but I want to make the page look good too.
Here's an example of the issue as it relates to HTML being rendered; here is an HTML page:
<!DOCTYPE html>

Cool, well to write that in something an Arduino can render, you use print statements; you might write:
// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println("<!DOCTYPE html>");

This won't work without a filesystem, or won't work as is.
Then, I tried inline SVG:
// listen for incoming clients
// forgoing all of server setup
EthernetClient client = server.available();
client.println("<!DOCTYPE html>");

This works, sometimes, but seems to have limitations as well.
I'm just wondering how I can make great looking webpages with stylesheets on an Arduino, only using print statements, or not requiring a filesystem.

https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

I can put files in there? storage I think isnt the issue. its that example.txt is a file pointer, not a datastream, or string literal that html / css is looking for. but that does give me an idea

Do a web search for “C++ raw string literal”. It is a convenient syntax for writing big, multi-line strings, that you can output on a single client.println().

https://stackoverflow.com/questions/12930978/array-of-strings-char-array-in-c-arduino-how-do-i-accomplish-it

oh, thanks, but html/css inline function havent worked for me yet doing that. I wrote a script a few days ago to handle that type of operation. its mainly that the url() in css seems to have limits on what it can do for images. I was using svg anyway, but if I werent.. wait, I think I read about this in PoC||GTFO

I'm not sure how it works on the teensy, but on the ESP chips you should use SPIFFS to store your website files and just serve them in your code (no string synthesis for serving the client html in code). You can even save images there, though high res images can fill the storage very fast. Also: When you want to design good looking websites have a look at Bootstrap. It provides many useful tools that already look good (buttons, tab bars, forms,...). If the client doesn't have internet connection, then you can even download bootstrap onto the ESP. Isn't that big.

yeah, spiffs seem like a neat feature, but I haven't seen anything like that for anything other than esp8266, and esp32 chips. maybe its not too hard to port, but I didn't look into it further.

Your method of embedding SVG seems unnecessarily complicated to me. You don't need to give a URL of anything. Below is valid for putting SVG onto a web page:
<!DOCTYPE html>

  <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
  <title>Test</title>

  <svg width="500" height="500">
    <rect x="5" y="5" width="450" height="450" fill="lightblue" stroke="black"></rect>
  </svg>

Hello, world

The "position:absolute" and the z-index styles put the SVG in a fixed position on the page (like a background image) and underneath anything else you might put there.

As I understand what you want to send is basically a big string(s) stored in memory. You can quite easily store it  it in external memory. You can use FRAM which is non volatile with 32K x 8 modules available for less then $5.00. They will run (Read / Write) at I2C or SPI speeds, no delays for writing or reading. There are other memory types that will also do the job but this is simple and inexpensive.
I am currently doing that with a project I am working on.  It is using an Arduino Nano with about 20K of messages and several of application / program data that I store. Flash will not contain the messages and the program, not enough room. The program data is created via sensors and a rotary switch. I load the data into the FRAM sometimes in sections depending on size with my loading code. I then go to my application code which retrieves the messages from the FRAM and displays them on the LCD and terminal.
There is a pointer table in a specific location in FRAM that is pointing to each message address, size etc. This allows messages and other data to change without changing the main code. The FRAM in my case is a plug in module. This approach although a bit convoluted works nicely and you do not have to have a file structure. You can if you want. I do not know if this will work for you but it does for me.

well, I still want to know more about writing great looking webpages on ardunio network devices.
I got my immediate issue sorted for now.
html/css seems to have some issues I dont quite understand as they relate to print statements, and Im pretty sure the url attribute is what is getting me.
I found this great github project that encodes svg for css inline functions.
https://yoksel.github.io/url-encoder/

I set up a basic web server example to simplify the code I was looking at.
its weird, on html pages I have put full style sheets on one line and never had a problem. here, it wouldn't work until I broke the style sheet into multiple lines (even with the url encoded svg).
Here is my simpler example for a page with a background image:
#include <SPI.h>
#include <NativeEthernet.h>
void  pageWrite(EthernetClient client);
void listenClient(EthernetClient client);
byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(10, 1, 0, 177);
EthernetServer server(80);
void setup() {

  delay(5000);  //you want this delay. reason: tl;dr
  Serial.begin(9600);
  Ethernet.begin(mac, ip);

if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
  // start the server
  server.begin();
  delay(100);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
} //end setup

void loop() {
      EthernetClient client = server.available();
listenClient(client);
}  //end loop
void listenClient(EthernetClient client){

   if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
       if (client.available()) {
          char c = client.read();
       // Serial.write(c);   //tells about the client connection
        if (c == '\n' && currentLineIsBlank) {
          pageWrite(client);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }//end avail
    } //end conect
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  } //end client
}//end listenClient()
void  pageWrite(EthernetClient client){
client.println("<!DOCTYPE html>");
    }

You can serve a whole webapp from spiffs. The ESP doesn't care if it's a pretty (e.g. javascript-based) webapp or a plain html file. The webapp can then communicate with the ESP via a socket connection. You wouldn't even have much webapp-related code in your sketch (beside of serving the webapp file). I personally would forget about this string synthesis in RAM completely.

very interesting, I will check that out.

Here's an alternative way of doing things I like to use:
What I like to do, when working with Arduinos with a decent amount of memory like the SAMD21-based ones, is create a fully self-contained webpage, that is, a webpage that has all HTML, CSS and Javascript in the same file, and all bitmap and SVG images in-lined in that same file. In short, a webpage file that is completely self-contained.
I then gzip that file (which compresses it a lot), and then base64 encode the gzipped file. The base64-encoded page is then copy/pasted into the code / memory as a const char*.
When the page needs to be served, I base64-decode it, and then serve the gzipped version, which all browsers accept if you put Content-Encoding: gzip in the header.
I put an elaborate example on Github, maybe you can get some inspiration from that. The webpage in the example is 26.8 kB in size, and the base64-encoded, gzipped webpage string as put into the code comes in at a little under 7 kB.

This is an interesting approach, but I do not see the usefulness in using base64 encoding. It makes your document consume 33% more memory, then you allocate the original size on the stack in order to decode it (at which point it occupies 233% of its size), and you need the extra code for decoding. It would be more efficient to store the gzipped page unencoded, as an array of bytes (not a C string).

@EdgarBonet: I know, but using base64 encoding makes it easier to copy/paste the contents of a file into the code without breaking it because of the control characters etc. in the gzip-ed file. I had enough memory, so I didn't go the more efficient way of escaping the problematic characters in the gzip output and use that. I will admit to some laziness here.

Gonna answer my own question again lol.
I looked at spiffs, but it seemed to just be an esp thing.
anyhow, I realized that <!DOCTYPE html>
probably wasn't the only doctype there is, and that svg would probably render just fine without html or css. which is true! I used <!DOCTYPE svg> and got rid of html and css, which means I didn't need to use some fancy inline css encoding, and could instead make much simpler println() statements, and still generate an accessible "webpage" written in only svg.
I could probably clean up the svg too, I drew it in inkscape, which generates overly complicated svg data.
But the project works now.. in a basic sort of way anyway.
/*
An IoT Etch-A-Sketch
uses 2 rotory encoders to generate x,y data points
in a svg poly line.

*/
#include <SPI.h>
#include <NativeEthernet.h>
#include <SD.h>
File dataFile;

byte mac[] = {
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};

IPAddress ip(10, 1, 0, 177);
EthernetServer server(80);
//Function defs
void rotors();
void rotorA(EthernetClient client);
void rotorB(EthernetClient client);
void resetImg();  //erase datalog.txt
void Abuton();
void Bbuton();
void listenClient(EthernetClient client);
void pageWrite(EthernetClient client);
void polyLineBegin(EthernetClient client);
void startPage(EthernetClient client);
void endPage(EthernetClient client);

//int potX = A0;
//int potY = A1;

int sensorValX = 0;
int sensorValY = 0;

int oldX = 0;
int oldY = 0;

/**Rotor Vars**/
// Rotary Encoder Input defintions
#define CLKA 2
#define DTA 3
#define SWA 4

#define CLKB 5
#define DTB 6
#define SWB 7

int Acounter = 0;
int Bcounter = 0;

int AcurrentStateCLK;
int BcurrentStateCLK;

int AlastStateCLK;
int BlastStateCLK;

unsigned long AlastButtonPress = 0; //butons on rotory encoders
unsigned long BlastButtonPress = 0;

void setup() {

  delay(10000);  //you want this delay. reason: tl;dr
  /** Set encoder pins as inputs **/
  pinMode(CLKA,INPUT);
  pinMode(DTA,INPUT);
  pinMode(SWA, INPUT_PULLUP);
  pinMode(CLKB,INPUT);
  pinMode(DTB,INPUT);
  pinMode(SWB, INPUT_PULLUP);

  // Read the initial state of CLK
  AlastStateCLK = digitalRead(CLKA);
  BlastStateCLK = digitalRead(CLKB);
  /***End Rotary Encoder vars****/

  Serial.begin(9600);

  Ethernet.begin(mac, ip);

if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  // start the server
  server.begin();
  delay(100);
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
  Serial.print("Initializing SD card...");

  if (!SD.begin(BUILTIN_SDCARD)) {
    Serial.println("SD Card init failed!");
    while (1);
    }
/****SD CARD and Ethernet intialized*****/
//if data file (on SD Card) Doesn't exist, create it.
//if data file (on SD Card) does exist errase it and create a new one
  if (SD.exists("datalog.txt")) {
     Serial.println("datalog.txt exists: \n Removing it.");
     while(SD.remove("datalog.txt")!=1){
       Serial.println("Deleeting old file data");
       if (SD.remove("datalog.txt")==1){
          Serial.println ("old dataFile removed");
       }
     }
  } else {
    Serial.println("datalog.txt doesn't exist.");
         }

  // open a new file and immediately close it:
  Serial.println("Creating datalog.txt...");
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  dataFile.close();

  // Check to see if the file exists:
  if (SD.exists("datalog.txt")) {
    Serial.println("datalog.txt exists.");
  } else {
    Serial.println("datalog.txt wasn't created.");
         }
} //end setup

void loop() {
 // listen for incoming clients
  EthernetClient client = server.available();
rotors();
listenClient(client);
}  //end loop
void listenClient(EthernetClient client){

   if (client) {
    boolean currentLineIsBlank = true;
    while (client.connected()) {
       if (client.available()) {
          char c = client.read();
       // Serial.write(c);   //tells about the client connection
        if (c == '\n' && currentLineIsBlank) {
          pageWrite(client);
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }//end avail
    } //end conect
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
  } //end client
  }//end listener()

void pageWrite(EthernetClient client){
          startPage(client);
          polyLineBegin(client);
          endPage(client);
  }
void startPage(EthernetClient client){
     // doctype svg no need for html
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
          client.println("Refresh: 1");  // refresh the page automatically every 5 sec
          client.println();
          client.println("<!DOCTYPE svg>");
          client.println("<svg   xmlns='http://www.w3.org/2000/svg'  viewBox='0 0 227.35277 156.29323' height='6.1532764in' width='8.9508963in'><path  style='fill:#ff0000; stroke:#ff0000; stroke-width:1.32300019;stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' d='m 12.000819,0.66145838 c -6.2819637,0 -11.33936062,5.05739692 -11.33936062,11.33936062 V 144.29249 c 0,6.28197 5.05739692,11.33936 11.33936062,11.33936 H 215.35224 c 6.28197,0 11.33885,-5.05739 11.33885,-11.33936 V 12.000819 c 0,-6.2819637 -5.05688,-11.33936062 -11.33885,-11.33936062 z M 18.932696,12.696383 H 205.5854 c 5.02557,0 9.07128,4.04571 9.07128,9.071282 v 77.03923 c 0,5.025575 -4.04571,9.071285 -9.07128,9.071285 H 18.932696 c -5.025572,0 -9.0712819,-4.04571 -9.0712819,-9.071285 v -77.03923 c 0,-5.025572 4.0457099,-9.071282 9.0712819,-9.071282 z' /><ellipse style='fill:#ffffff;fill-opacity:1; stroke:#ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1' cx='21.16666'  cy='130.59085'  rx='10.583334' ry='9.0714283' /><ellipse  style='fill:#ffffff; fill-opacity:1; stroke:#ff0000; stroke-width:1.32300007; stroke-miterlimit:4; stroke-dasharray:none;stroke-opacity:1' cx='200.62982'   cy='131.57361' rx='10.583334' ry='9.0714283'/>");
          client.println("\n<polyline points='15,15");
   }
 void endPage(EthernetClient client){
  client.print("' \nfill='none' stroke='#ff0000'/></svg>");
   }
void polyLineBegin(EthernetClient client){
//read data points from SD card
    File dataFile = SD.open("datalog.txt");
  // if the file is available, read it:
  if (dataFile) {
    while (dataFile.available()) {
      //Serial.write(dataFile.read());
      client.write(dataFile.read());
    }
    dataFile.close();
  }
}

int rotorA(){ //X coords
  AcurrentStateCLK = digitalRead(CLKA);
  if (AcurrentStateCLK != AlastStateCLK  && AcurrentStateCLK == 1){
     if (digitalRead(DTA) != AcurrentStateCLK) {
      Acounter --;
      }else{
       Acounter ++;
       }
     }
// Remember last CLK state
  AlastStateCLK = AcurrentStateCLK;
Abuton(); //errase the data file if A button pressed.
//X limits
if(Acounter<=15){
  Acounter=15;
  }
if(Acounter>=215){
  Acounter=215;
  }
return Acounter;
  }//endA rotor

int rotorB(){ //Y coords
  BcurrentStateCLK = digitalRead(CLKB);
  if (BcurrentStateCLK != BlastStateCLK  && BcurrentStateCLK == 1){
    if (digitalRead(DTB) != BcurrentStateCLK) {
       Bcounter --;
       }else{
        Bcounter ++;
     }
    //Serial.println(Bcounter);
  }
  BlastStateCLK = BcurrentStateCLK;
Bbuton();
//Y limits
if(Bcounter<=15){
  Bcounter=15;
  }
if(Bcounter>=210){
  Bcounter=210;
  }
  return Bcounter;
  }//EndB rotor

void rotors(){
//read rotors and write x,y points to datalog.txt
 sensorValX=rotorA();
 sensorValY=rotorB();
String dataString = "";

if(sensorValX!=oldX || sensorValY!=oldY){
   dataString += ",";
   dataString += String(sensorValX);
   dataString += ", ";
   dataString += String(sensorValY);

   Serial.println(dataString);

   dataFile = SD.open("datalog.txt", FILE_WRITE);
    // if the file is available, write to it:
   if (dataFile) {
      dataFile.print(dataString);
      dataFile.close();
      //clear dataString
      dataString="";
      }else{
    // if the file isn't open, pop up an error:
    Serial.println("error opening datalog.txt");
  }
  dataFile.close();
  }else{
  ;
  }

 oldX=sensorValX;
 oldY=sensorValY;

}//end rotors
void resetImg(){
  //clear datapoints by errasing datafile.
  if (SD.exists("datalog.txt")) {
     Serial.println("Deleting data.");
     while(SD.remove("datalog.txt")!=1){
       Serial.println("Deleeting old file data");
       if (SD.remove("datalog.txt")==1){
          Serial.println ("old dataFile removed");
       }
     }
  } else {
    Serial.println("datalog.txt doesn't exist.");
         }

  // open a new file and immediately close it:
  Serial.println("Creating datalog.txt...");
  dataFile = SD.open("datalog.txt", FILE_WRITE);
  dataFile.close();

  // Check to see if the file exists:
  if (SD.exists("datalog.txt")) {
    Serial.println("New datalog.txt created.");
  } else {
    Serial.println("datalog.txt wasn't created.");
         }

  }//end resetImg

void Abuton(){ //X buton
    int AbtnState = digitalRead(SWA);
  //If we detect LOW signal, button is pressed
if (AbtnState == LOW) {
    if (millis() - AlastButtonPress > 500) {
      Serial.println("Resting image!");
      resetImg();
    }
  AlastButtonPress = millis();
  }
  } //end Abuton

void Bbuton(){ //Y buton
int BbtnState = digitalRead(SWB);
    if (BbtnState == LOW) {
    //if 50ms have passed since last LOW pulse, it means that the
    //button has been pressed, released and pressed again
    if (millis() - BlastButtonPress > 50) {
      Serial.println("Button B pressed!");
    }
    BlastButtonPress = millis();
  }
}

Note that, if you send SVG, you don't need the DOCTYPE line, but you should fix the Content-Type: it should be "image/svg+xml", not "text/html".

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


text:
How can I execute a string in my Arduino Uno board?
I was making a project with Arduino Uno ,
It's working is like this it connects to a key pad and a 7segment display ,and when you press a run button connected to Arduino it should run the code written.
I don't want code for display and keypad but for executing a string like we can do in python- exec("print (8)")
Please help me and ask any information you need to solve it

There's a technical answer to your question.  But a more practical answer can probably be given if you explain why you would want to do this on an UNO.

you could try forth ... it's not python, but it is interpreted ... https://arduino-forth.com/ .... you could write some forth words to emulate some of the python commands

Unless you want to implement some form of scripting engine, you can't.
Arduino code is compiled code, not interpreted code. There is no way of converting text into runnable code, since that is done by your computer at compile time, not by the Arduino at run-time.
The only thing you could possibly do is write some form of scripting engine which reads text and interprets it in some meaningful way to perform operations. That is not a trivial task, so you have to ask yourself: is this really what you want to do? Are you going about tackling your problem in the right way?

Things like reflection in higher level languages that would make this an “easier” task aren’t available in C++

As stated in Majenko's answer, you would need an interpreter running on
the Arduino. Python is too large to run on an Uno, although it can run
on some more powerful microcontrollers.
A Web search for Arduino interpreters yields quite a few promising
options. I have not tested any of them:

Firmata
Forth
another Forth-ish language
Lisp
BASIC
a C-like language

The Forth language is quite popular when you need an interpreter with
minimal footprint.


text:
Wire.endTransmission(false) hanging the program after running once when using MPU6050
For this project, I was using an Elegoo Car V3 and I was trying to add a gyroscope onto it. When I run the code for the car, my loop code iterates once and it is always able to read the sensor data. But after that, the program starts hanging. I traced back the problem to the Wire.endTransmission(false) line in my code. For some reason, that line was not completing the second time.
I spent a few hours trying to find a solution online. I triple checked my wiring and still, I could not find a solution to this problem.
Thank you for taking the time to help me!
This is the output of the program
RawX= 82
RawY= 241
RawZ= -1
-----------------------------------------
AngleX= 195.41
AngleY= 216.93
AngleZ= 200.14
-----------------------------------------

And this is the code

#include <Wire.h>

const int MPU_addr = 0x68;
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;

int minVal = 265;
int maxVal = 402;

double x;
double y;
double z;
int c = 0;

//www.elegoo.com

//     Right motor truth table
//Here are some handy tables to show the various modes of operation.
//  ENB         IN3             IN4         Description
//  LOW   Not Applicable   Not Applicable   Motor is off
//  HIGH        LOW             LOW         Motor is stopped (brakes)
//  HIGH        LOW             HIGH        Motor is on and turning forwards
//  HIGH        HIGH            LOW         Motor is on and turning backwards
//  HIGH        HIGH            HIGH        Motor is stopped (brakes)

// define IO pin
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

//set car speed
#define CAR_SPEED 100
typedef unsigned char u8;  //Change the name of unsigned char to u8

void forward(u8 car_speed)
{
  analogWrite(ENA, car_speed);
  analogWrite(ENB, car_speed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void back(u8 car_speed)
{
  analogWrite(ENA, car_speed);
  analogWrite(ENB, car_speed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

void left(u8 car_speed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);

  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
}

void right(u8 car_speed)
{
  analogWrite(ENA, 250);
  analogWrite(ENB, 250);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
}

void stop()
{
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
}

int getGyroData() {
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);
    Wire.endTransmission(false);

    Wire.requestFrom(MPU_addr,6,true);
    AcX = Wire.read()<<8|Wire.read();
    AcY = Wire.read()<<8|Wire.read();
    AcZ = Wire.read()<<8|Wire.read();

    int xAng = map(AcX, minVal, maxVal,-90, 90);
    int yAng = map(AcY, minVal, maxVal,-90, 90);
    int zAng = map(AcZ, minVal, maxVal,-90, 90);

    x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
    y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
    z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

    Serial.print("AngleX= ");
    Serial.println(x);

    Serial.print("AngleY= ");
    Serial.println(y);

    Serial.print("AngleZ= ");
    Serial.println(z);
    Serial.println("-----------------------------------------");

}

void turn(int degrees) {
    int *originalData;
    originalData = getGyroData();
    int originalTurn = originalData[2];

    bool notDone = true;

    while (notDone) {

        int *newVal;
        newVal = getGyroData();
        int newTurn = newVal[2];

        int change = originalTurn - newTurn;
        Serial.println(change);
    }
}

void setup(){
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);
  Wire.write(0);
  Wire.endTransmission(true);
  pinMode(IN1, OUTPUT);//before useing io pin, pin mode must be set first
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  Serial.begin(9600);

}

void loop(){
    c++;

    Serial.println(c);
    Wire.beginTransmission(MPU_addr);
    Serial.println(c);
    Wire.write(0x43);
    Serial.println(c);
    Wire.endTransmission(false);

    Serial.println(c);
    Wire.requestFrom(MPU_addr,4,true);
    AcX = Wire.read()<<8|Wire.read();
    AcY = Wire.read()<<8|Wire.read();
    AcZ = Wire.read()<<8|Wire.read();
    Serial.println(c);

    Serial.print("RawX= ");
    Serial.println(AcX);

    Serial.print("RawY= ");
    Serial.println(AcY);

    Serial.print("RawZ= ");
    Serial.println(AcZ);
    Serial.println("-----------------------------------------");

    int xAng = map(AcX, minVal, maxVal,-90, 90);
    int yAng = map(AcY, minVal, maxVal,-90, 90);
    int zAng = map(AcZ, minVal, maxVal,-90, 90);

    x= RAD_TO_DEG * (atan2(-yAng, -zAng)+PI);
    y= RAD_TO_DEG * (atan2(-xAng, -zAng)+PI);
    z= RAD_TO_DEG * (atan2(-yAng, -xAng)+PI);

    Serial.print("AngleX= ");
    Serial.println(x);

    Serial.print("AngleY= ");
    Serial.println(y);

    Serial.print("AngleZ= ");
    Serial.println(z);
    Serial.println("-----------------------------------------");
    delay(500);

}

This is a schematic of the car I found

In the comments below, @chrisl makes something explicit that I hadn't in previous edits.  Reading it first may make the below easier to interpret:

Useful fact about I2C on Arduino: Wire.endTransmission() is the
function, that actually does the I2C communication. Before that (all
the Wire.beginTransmission() and Wire.write() calls) no data will run
over the bus, just placed inside the libraries buffer. Thus a hanging
Wire.endTransmission() equals a blocked I2C bus.

On the UNO the A4 and A5 are SDA and SCL, the same signals that are available near AREF and pin 13 on the other side of the board.
So, the ultrasonic range finder in the picture is attached the signals that are needed to operate the I2C ("Wire") bus, and may easily be interfering with Wire.endTransmission(false).  One of the I2C signals is probably causing the range finger to trigger during I2C traffic.  After each trigger, the echo signal from the range finder would then interfere with the connected I2C bus signal.
You could try bit banging I2C using a library instead of the native I2C that is on A4/A5, and use that to operate your gyroscope.  According to your diagram, A0 through A3 are unused, and seem to be the only signals unused from the UNO.  Despite being "analog" pins they function as digital pins also and should work fine for bit-banging.  Getting to them may be a pain though, since the shield doesn't seem to make them available again as pins.
Or you may be able to route the ultrasonic sensor away from A4/A5 either by not plugging it into the header on the shield and instead route the signals from the plug to where an unused set of pins is available (again A0 though A3) and then updating the code accordingly.  Another possibility might be leave it plugged into the shield but bend the A4 and A5 pins to the side so they don't enter the UNO below, and use jumpers to route them from the bent pins to some other pair of available pins; you won't be able to bend them back and forth more than once or twice, so I would be careful with trying that.

Useful fact about I2C on Arduino: Wire.endTransmission() is the function, that actually does the I2C communication. Before that (all the Wire.beginTransmission() and Wire.write() calls) no data will run over the bus, just placed inside the libraries buffer. Thus a hanging Wire.endTransmission() equals a blocked I2C bus.

Yeah, I probably should have been explicit about that.  Will edit it later to incorporate your comment.

@timemage This worked like a charm! Removing the ultrasonic sensor allowed the gyro to function. Thank you for answering so quickly! I just wanted to ask you why the A4 and A5 pins are used for the SDA and SCL communications pins. Can I use any other analog pins for the Gyro?

I may try to update the answer to be more explicit that.  A pin on the AVR may have have special functions beyond being a plain GPIO pin (digitalRead/digitalWrite capable) or connected to the analog to digital converter (analogRead capable).  I2C/TWI "Wire" is a special function found only on the A4 an A5 pins of the UNO.  The ultrasonic sensor by comparison uses only generic GPIO functionality that can be had on nearly any pin.  So it makes sense to put the gyro on A4/A5 and move the ultrasonic sensor to A0-A3 when that's possible.

Using I2C/Wire without the aid of the chip's native support for I2C is what "bit banging" means essentially.

To clarify, the the fact that native I2C/Wire functionaly exists on the same pins as some analog input functionality is a matter of how the ATMega328P chip was constructed and not a design choice made for the Arduino UNO.


text:
How to change ArduinoOTA upload timeout?
I'm using ESP8266WiFiMulti, ESP8266WebServer and ArduinoOTA to communicate with my device and perform over-the-air-updates. Everything was working perfectly until I moved the ESP8266 further from the WiFi router. The OTA upload slowed down, which caused upload timeouts after 5 seconds. It fails at a different point each time, usually between 30% and 60%.
How do I increase the OTA timeout to 30 seconds?
Here is the setup code, let me know if you need more:
void startWiFi() {
    ESP8266WiFiMulti wifiMulti;
    wifiMulti.addAP(ssid, password);
    wifiMulti.run();
}

void startOTA() {
    ArduinoOTA.setHostname(_hostname);
    ArduinoOTA.setPassword(_password);

    ArduinoOTA.onStart([]() {
        Serial.println("Start OTA");
    });
    ArduinoOTA.onEnd([]() {
        Serial.println("\nEnd OTA");
    });
    ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
        Serial.printf("OTA Progress: %u%%\r", (progress / (total / 100)));
    });
    ArduinoOTA.onError([](ota_error_t error) {
        Serial.printf("Error[%u]: ", error);
        if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
        else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
        else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
        else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
        else if (error == OTA_END_ERROR) Serial.println("End Failed");
    });
    ArduinoOTA.begin();
}

The only timeout I can find is in the espota.py script itself. That is riddled with such lines as:
sock.settimeout(10)

You would need to scour that program and change them all.
However
ArduinoOTA uses UDP for communication. Because of that it is unreliable (yes, that's a technical term). It doesn't have any form of retransmit / retry, so if a packet is lost it's lost for good. No amount of increasing of timeouts will make that packet reappear.
So increasing your timeouts most likely will just make it wait longer before failing.
You should consider switching to a more reliable update system which uses TCP instead of UDP - such as downloading an update from a website using ESP8266httpUpdate.
Update:
ArduinoOTA uses a combination of both UDP (to initialise and authenticate the connection) and TCP (to make a "back channel" connection back to your computer) to download the actual binary.
The same still applies: you will need to alter the espota.py program to change its timeouts (sock2 is the back-channel object), but there is also one line in ArduinoOTA.cpp that will need to be altered to increase timeouts.  Line 294:
int waited = 1000;

This is not strictly the number of milliseconds to wait for incoming data, but it's not far off - it's a 1 millisecond delay in a loop while looking for incoming data.  Increasing that will allow more time for the ESP8266 to wait for data to arrive.
But of course, with an unstable WiFi connection YMMV...

Thanks for the reply! What's the point of using UDP for firmware upgrades, a critical function? I'm using LittleFS file system, so I can also upload the file, then find a library to do the program switch.

It's fast, easy to implement packets, light weight and reliable enough for most uses. You're a corner case.

I meant why does ArduinoOTA use UDP instead of TCP? That seems like a bad design decision. Firmware updates should be lossless.

For the reasons I just stated. It's considerably easier and lighter weight and faster to write a packet based protocol using UDP compared to TCP.

No! It's not unreliable software. UDP is an unreliable protocol. Not that is flakey or badly written. It is unreliable. It's the official term for that kind of protocol. A protocol with no built in retransmit facility is called unreliable. ArduinoOTA is very well written and is itself very reliable and secure. The fact that it doesn't work on your network is down to your network losing packets. Get a better wi-fi signal or don't use ArduinoOTA. It's intended for development, not production. No one in their right mind would use ArduinoOTA for production, they'd use an HTTP server based.

You're right, I just chose the wrong library for my needs. I should have designed for being able to change rooms. I will find a more reliable solution. Thanks for your answer!

@Majenko The official term is connectionless which simply means the UDP protocol has no provisions for the receiver of a packet of sending an Acknowledgement to let the sender know each packet has been received. That does not mean you can't build reliable protocols using UDP. Reliability has to come from higher level protocols built on top of UDP.

@Majenko, espota.py and the ArduinoOTA library uses TCP to transfer the binary

@Juraj So it does. It initiates the connection with UDP first then the ESP8266 makes a reverse connection to the computer running espota.py to pull down the binary. Serves me right for trying to decipher Python at 2 in the morning. It's bad enough at the best of times when I'm full of coffee...

@StarCat Back when I was at university it was called Unreliable vs Reliable transmission. Transmission that doesn't retry vs transmission that retries. Maybe it's a regional thing.

@Majenko, it seems you are also correct, although there is a difference between the definition of an unreliable protocol and a connectionless protocol (had to look it up). For UDP both are true.

@StarCat Connectionless is about state, reliability is about re-sending packets. The two are usually used or not used in tandem. I guess you could have a stateless (connectionless) reliable protocol, or a stateful (connectionful?) unreliable protocol...


text:
Trying to install amforth on Leonardo board
Just got a Arduino Leonardo (with headers) dropped in my lap this week. I've tried experimenting with the Arduino C++ IDE and find it awkward. I have some previous experience with Forth and would like to try loading amforth directly onto the ATmega32u4 microcontroller.
I found some "how to" information on the web but find it confusing and contradictory. Can anyone point to some easy to follow instructions? I'd greatly appreciate it!
In case it matters, my development box is a Fedora 29 workstation.

what are easy to follow instructions? ..... which information did you find? .....  how was it contradictory?

https://arduino.stackexchange.com/questions/24969/amforth-on-arduino-uno

Instructions that make no assumptions about any experience with the board.

Oh BTW, I have but one Leonardo board and the example "wiring" diagram in the link above show 2 Leonardo boards. I assume that's not necessary to use amforth?


text:
Does not execute code on loop;only run code of set up
only display this:
ARDUMOTIVE
ArduinoBased
compassn.Compass
Michalis Vas.

nothing else. I tried another Arduino Uno, Mega, Nano, but execute only set up. Display is working.No compiler errors.Sketch upload it with out errors!!
i found here https://www.instructables.com/id/Arduino-Digital-Magnetic-Compass-HMC5883L-2-displa/
Code is here.Thank you.
`*          Ardumotive.com Project Corner
   Arduino digital magnetic Compass with two display modes
   using 3-Axis Digital Compass IC HMC5883L board
   Dev. Vasilakis Michalis / Ver. 1.0 / Date:17/3/2015      */

//Include libraries
#include <SPI.h>
#include <Wire.h>
#include <Button.h>
#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>
#include <Adafruit_HMC5883_U.h>
#include <Adafruit_Sensor.h>

//Init Display (SCLK, DIN, D/C, CS, RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(7, 6, 5, 4, 3);
//Init HMC5883L sensor
Adafruit_HMC5883_Unified compass = Adafruit_HMC5883_Unified(12345);

//Constants
const int lcdLight = 13; //BL pin of LCD to arduino pin 13 (BL = Back Light)
Button buttonA = Button(2,HIGH); //Button to turn on/off display light
Button buttonB = Button(8,HIGH); //Button for changing display mode
// For 1st display mode:
static unsigned char Leters[] = { 'N' , 'E' , 'S' , 'W' };
const static unsigned char PROGMEM arrow_bmp[] ={B00100000, B00100000, B01110000, B01110000, B11111000,};
// For 2nd display mode:
int r = 24; // radius of compass rose
int x0= 60; // x-origin
int y0= 24; // y-origin

//Variables
int flag=0;//Store buttonA condition 0:1st display mode / 1: 2nd display mode
int i=1;   //Store buttonB condition 1: light on / 0: light off

void setup() {
  pinMode(lcdLight, OUTPUT); // lcd led
  compass.begin();
  Wire.begin();
  display.begin();
  display.setContrast(60);
  //Print a welcome message in startup for 6sec.//////////
  digitalWrite(lcdLight,HIGH);
  display.clearDisplay();   // clears the screen and buffer
  display.setTextColor(BLACK);
  display.setCursor(0,2);
  display.print("  ARDUMOTIVE  ");
  display.setCursor(0,13);
  display.print(" ArduinoBased ");
  display.setCursor(0,23);
  display.print(" compassn.Compass ");
  display.setCursor(0,33);
  display.print(" Michalis Vas.");
  display.display(); // show splashscreen
  digitalWrite(lcdLight,LOW);
  delay(6000);
  /////////////////////////////////////////////////////////
  display.clearDisplay();   // clears the screen and buffer
}

void loop() {

  //if buttonB is pressed, 'flag' will change between 0 and 1
    if(buttonB.isPressed()){
      delay(100);//small delay
    if(flag==0){ flag=1; }
    else{ flag=0; }
  }
  //if buttonA is pressed, 'i' will change between 0 and 1
  if(buttonA.isPressed()){
    if(i==0){ i=1; }
    else{ i=0; }
  }
  //if i is equal with 0, set display light on, else set display light off
    if (i==0){
  digitalWrite(lcdLight,HIGH);}
    else{
  digitalWrite(lcdLight,LOW);
   }
  //Reading and calculate degrees:   /////////////////////////////////////
  //Get new sensor value every time that loop starting again
  sensors_event_t event;
  compass.getEvent(&event);
  //Variable heading stores value in radians
  float heading = atan2(event.magnetic.y, event.magnetic.x);

  // Once you have your heading, you must then add your 'Declination Angle', which is the 'Error' of the compassnetic field in your location.
  // Find yours here: http://www.compassnetic-declination.com/
  // Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
  float declinationAngle = 0.22;  //<--Change 0.22 with yours. If you can't find your declination juct delete those lines ;)
  heading += declinationAngle;
  // Correct for when signs are reversed.
  if(heading < 0)   heading += 2*PI;
  // Check for wrap due to addition of declination.
  if(heading > 2*PI)heading -= 2*PI;
  // Convert radians to degrees for readability.
  float headingDegrees = heading * 180/M_PI;
  //Convert float to int
  int angle=(int)headingDegrees;
  //////////////////////////////////////////////////////////////////////////

  display.clearDisplay(); // Just in case...

  //if flag is equal with 0 - 1st Display Mode
  if (flag==0){
  DrawRow(angle); //call DrawRow function
  display.drawBitmap(40, 24,  arrow_bmp, 5, 5, 1);
  display.drawLine(42, 0, 42, 24, BLACK);
  display.setCursor(32,34);
  display.print(angle);
  display.setTextSize(1);
  display.print("o");
  display.display();
  delay(500); //print new value every 0.5sec
  }

  //if flag is equal with 1 - 2nd Display Mode
  if (flag==1){
  // Calculation of compass needle on lcd pointing to the direction
  DrawCircle(angle); //call DrawCircle function
  // Display actual heading
  display.setTextSize(2);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  display.println(angle);

  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(x0-2,0);
  display.println("N");

  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor((x0+r)-5,y0-3);
  display.println("E");

  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(x0-2,y0+r-8);
  display.println("S");

  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor((x0-r)+5,y0-3);
  display.println("W");

  // Triangle for direction
  display.drawTriangle(0, 46, 20, 46, 10, 18, BLACK);
  display.fillTriangle (0, 46, 20, 46, 10, 18, BLACK);
  display.display();
  delay(500); //print new value every 0.5sec
  }
}/// end of program

////////////      Functions    ////////////

//Draw rows and print letters to display - 1st Display Mode
void DrawRow(int angle) {

  display.drawLine(0, 0, 84, 0, BLACK);
  display.drawLine(0, 1, 84, 1, BLACK);

  display.drawLine(0, 22, 91, 22, BLACK);
  display.drawLine(0, 23, 95, 23, BLACK);

  display.setTextSize(2);
  display.setTextColor(BLACK);

  int start = 42 - angle / 3 ;
  if (start > 120) start += -120 ;

  int x = 0 ;
  int y = 18 ;
  for (int i=0; i<4; i++) {
      x = start + (i*30) -1;
      if (x>119) x += -120;
      display.drawPixel(x+1, y-2, 1);
      display.drawPixel(x, y, 1);
      display.drawPixel(x+1, y, 1);
      display.drawPixel(x+2, y, 1);
      display.drawPixel(x, y-1, 1);
      display.drawPixel(x+1, y-1, 1);
      display.drawPixel(x+2, y-1, 1);
      display.setCursor((x-4),(y-16));
      display.write(Leters[i]);
   }
  for (int i=0; i<24; i++) {
      x = start + (i*5) -1;
      if (x>119) x += -120;
      display.drawPixel(x+1, y+1, 1);
      display.drawPixel(x, y+2, 1);
      display.drawPixel(x+1, y+2, 1);
      display.drawPixel(x+2, y+2, 1);
      display.drawPixel(x, y+3, 1);
      display.drawPixel(x+1, y+3, 1);
      display.drawPixel(x+2, y+3, 1);
   };

  for (int i=0; i<8; i++) {
      x = start + (i*15)-1;
      if (x>119) x += -120;
      display.drawPixel(x+1, y-1, 1);

      display.drawPixel(x, y, 1);
      display.drawPixel(x+1, y, 1);
      display.drawPixel(x+2, y, 1);
      display.drawPixel(x, y+1, 1);
      display.drawPixel(x+1, y+1, 1);
      display.drawPixel(x+2, y+1, 1);

   };
}

////Draw circle and print letters to display - 1st Display Mode
void DrawCircle(int angle) {
  if (angle >= 0 && angle <=45) {    // 0-45 degrees
    int angle = angle/2;
    display.drawLine(x0, y0, x0+angle, y0-r, BLACK);
  }
  else if (angle >45 && angle <=90) {// 46-90 degrees
    int angle = (angle-44)/2 ;
    display.drawLine(x0, y0, x0+r, (y0-r)+angle, BLACK);
  }
  else if (angle >90 && angle <=135) {// 91-135 degrees
    int angle = (angle-90)/2;
    display.drawLine(x0, y0, x0+r, y0+angle, BLACK);
  }
  else if (angle >135 && angle <=180){// 136-180 degrees
    int angle = (angle-134)/2;
    display.drawLine(x0, y0, (x0+r)-angle, y0+r, BLACK);
  }
  else if (angle >180 && angle <=225){// 181-225 degrees
    int angle = (angle-178)/2;
    display.drawLine(x0, y0, x0-angle, y0+r, BLACK);
  }
  else if (angle >225 && angle <=270){// 226-270 degrees
    int angle = (angle-222)/2;
    display.drawLine(x0, y0, x0-r, (y0+r)-angle, BLACK);
  }
  else if (angle >270 && angle <=315){// 271-315 degrees
    int angle = (angle-270)/2;
    display.drawLine(x0, y0, x0-r, y0-angle, BLACK);
  }
  else if (angle >315 && angle <=360){// 316-360 degrees
    int angle = (angle-312)/2;
    display.drawLine(x0, y0, (x0-r)+angle, y0-r, BLACK);
  }
}

it doesn't even clear after 6 seconds?

Please give links to the modules of the display and the magnetometer that you use. How are they connected? Do you use extra resistors or extra level shifters? You could send messages to the serial port, to know what is going on.

And start debug, by adding Serial.Print in the loop you can verify if it is running or not. There is also a more comprehensive library available for debugging, https://playground.arduino.cc/Code/SerialDebugger

no,it does not clear after 6 seconds.I tried with same pin connection the lcd nokkia 5510 the scetch of Adafruit_PCD8544 library sketch pcdtest and lcd works fine.I also put in if{} and code  display.print("  something  "); to see if code execute and enter in loop,but nothing.I now try serial print to see what happen (like MatsK said).Is first time happens someting like it to me.Thank you very much  all for your help.

lcd screen 51110 is this https://www.aliexpress.com/item/High-Quality-8448-84x84-LCD-Module-blue-backlight-adapter-PCB-for-Nokia-5110-for-Arduino/32614334972.html?spm=a2g0s.12269583.0.0.313e7cdfn3UXYH

As you have a lot of test in the loop; I'll suggest first to add a "Serial.println("here"); at the beginning of the loop in order to see if yo enter the loop. Then, print some message in each "if/else" to see what's happening.

i edit code and add serial print.Now serial is  printing when button A or B  is pressed,flag when change 0 or 1,i  when change 0 or 1(all this execute in the loop!),but does not lcd print nothing,only freeze in first message of set up-->ARDUMOTIVE
ArduinoBased
compassn.Compass
Michalis Vas.   i believe,but i can not find,that maybe sensor is faulty and code allow display to show data of digital compass,ONLY when sensor send data!!!but i can not find this in code to overide,if is exist;Any help;

thank you very much all.I delete code of the compass sensor,overided it,and now lcd show graphics of digital compass,but no data.The sensor do not working.thank you very much all for you value help.I will buy another sensor module compass.

You might run into the same problem with a new sensor. The 5110 is sold as 3.3 to 5v, but it is not for 5v, only for 3.3v. We would like to know if you use a resistor for the backlight. Do you use a breadboard? Some breadboards have bad contacts. Sparkfun has a guide for the 5110 connected to a 5v arduino board: https://learn.sparkfun.com/tutorials/graphic-lcd-hookup-guide/all The HMC5883L magnetometer is a 3.3v chip. We do not know which module you have and how you have connected a 5v arduino board to a 3.3v sensor.


text:
Arduino stuck when I disable Timer 2 Interrupt
#define TIM2_EN() (TIMSK2 = 0x02)
#define TIM2_DIS() (TIMSK2 = 0x00)

//HEART SENSOR
// Include Libraries
#include "Arduino.h"

class PulseSensor
{
public:
  static void begin(int pulsePin);

  static volatile int BPM;           // used to hold the pulse rate
  static volatile int Signal;        // holds the incoming raw data
  static volatile int IBI;           // holds the time between beats, must be seeded!
  static volatile boolean QS;        // becomes true when Arduoino finds a beat.
};

// Pin Definitions
#define HEARTPULSE_PIN_SIG  A0

// Global variables and defines

// object initialization
PulseSensor heartpulse;

volatile int rate[10];                        // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;     // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;      // used to find IBI
volatile int P =512;                          // used to find peak in pulse wave, seeded
volatile int T = 512;                         // used to find trough in pulse wave, seeded
volatile int thresh = 512;                    // used to find instant moment of heart beat, seeded
volatile int amp = 100;                       // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;            // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;          // used to seed rate array so we startup with reasonable BPM
volatile boolean Pulse = false;               // true when pulse wave is high, false when it's low
volatile int pulsePin;

volatile int PulseSensor::IBI = 600;          // holds the time between beats, must be seeded!
volatile int PulseSensor::BPM;                // used to hold the pulse rate
volatile int PulseSensor::Signal;             // holds the incoming raw data
volatile boolean PulseSensor::QS = false;     // becomes true when Arduino finds a beat

void PulseSensor::begin(int pPin)
{
  pinMode(pulsePin, INPUT);
  pulsePin = pPin;

  // Initializes Timer1 to throw an interrupt every 2ms.
  TCCR1A = 0x00;
  TCCR1B = 0x0C;  // CTC (Compare match mode) and ClockIO/256
  OCR1A = 0x7C;   // 2 ms
  TIMSK1 = 0x02;
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}

// THIS IS THE TIMER 1 INTERRUPT SERVICE ROUTINE.
// Timer 1 makes sure that we take a reading every 2 miliseconds
ISR(TIMER1_COMPA_vect)
{                         // triggered when Timer1 counts to 124
  cli();                                      // disable interrupts while we do this
  PulseSensor::Signal = analogRead(pulsePin);              // read the Pulse Sensor
  sampleCounter += 2;                         // keep track of the time in ms with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise

  //  find the peak and trough of the pulse wave
  if(PulseSensor::Signal < thresh && N > (PulseSensor::IBI/5)*3){       // avoid dichrotic noise by waiting 3/5 of last IBI
    if (PulseSensor::Signal < T){                        // T is the trough
      T = PulseSensor::Signal;                         // keep track of lowest point in pulse wave
    }
  }

  if(PulseSensor::Signal > thresh && PulseSensor::Signal > P){          // thresh condition helps avoid noise
    P = PulseSensor::Signal;                             // P is the peak
  }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250){                                   // avoid high frequency noise
    if ( (PulseSensor::Signal > thresh) && (Pulse == false) && (N > (PulseSensor::IBI/5)*3) )
    {
      Pulse = true;                               // set the Pulse flag when we think there is a pulse
      PulseSensor::IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
      lastBeatTime = sampleCounter;               // keep track of time for next pulse

      if(secondBeat){                        // if this is the second beat, if secondBeat == TRUE
        secondBeat = false;                  // clear secondBeat flag
        for(int i=0; i<=9; i++){             // seed the running total to get a realisitic BPM at startup
          rate[i] = PulseSensor::IBI;
        }
      }

      if(firstBeat){                         // if it's the first time we found a beat, if firstBeat == TRUE
        firstBeat = false;                   // clear firstBeat flag
        secondBeat = true;                   // set the second beat flag
        sei();                               // enable interrupts again
        return;                              // IBI value is unreliable so discard it
      }

      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable

      for(int i=0; i<=8; i++){                // shift data in the rate array
        rate[i] = rate[i+1];                  // and drop the oldest IBI value
        runningTotal += rate[i];              // add up the 9 oldest IBI values
      }

      rate[9] = PulseSensor::IBI;                          // add the latest IBI to the rate array
      runningTotal += rate[9];                // add the latest IBI to runningTotal
      runningTotal /= 10;                     // average the last 10 IBI values
      PulseSensor::BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
      PulseSensor::QS = true;                              // set Quantified Self flag
      // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }
  }

  if (PulseSensor::Signal < thresh && Pulse == true){   // when the values are going down, the beat is over
    Pulse = false;                         // reset the Pulse flag so we can do it again
    amp = P - T;                           // get amplitude of the pulse wave
    thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
    P = thresh;                            // reset these for next time
    T = thresh;
  }

  if (N > 2500){                           // if 2.5 seconds go by without a beat
    thresh = 512;                          // set thresh default
    P = 512;                               // set P default
    T = 512;                               // set T default
    lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date
    firstBeat = true;                      // set these to avoid noise
    secondBeat = false;                    // when we get the heartbeat back
  }

  sei();                                   // enable interrupts when youre done!
} // end isr

//LDR SENSOR
int sensorPin = A1; // select the input pin for LDR
int sensorValue = 0; // variable to store the value coming from the sensor

//LCD
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

//DHT
#include "dht.h"
int dht_apin = 2;
dht DHT;

//HEART RATE SENSOR
unsigned long current_time,start_time=0;
int BPM,Interval;

void setup(){

  Serial.begin(115200);
  heartpulse.begin(HEARTPULSE_PIN_SIG);
  delay(1500);
  lcd.init();          // initialize the lcd
  lcd.backlight();
  lcd.print("  INITIALISING");
  delay(2500);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" CHECKING HEART");
  lcd.setCursor(0,1);
  lcd.print(" RATE NOW......");
  delay(2000);
  lcd.clear();
}

void loop() {

  current_time = millis();
  if ( current_time-start_time < 30000 )  {
    BPM = heartpulse.BPM;
    Interval = heartpulse.IBI;
    lcd.print(" SYNCHRONIZING  ");
    lcd.setCursor(0,1);
    lcd.print("   BEATS:");
    lcd.print(BPM);
    lcd.clear();
  } else  {
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("BEATS PER MINUTE");
    lcd.setCursor(6,1);
    lcd.print(BPM);
    Serial.print(BPM);
    Serial.println('b');
    delay(4000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" BEAT INTERVAL  ");
    lcd.setCursor(7,1);
    lcd.print(Interval);
    Serial.print(Interval);
    Serial.println('p');
    delay(4000);
    TIM2_DIS(); //Enable TIMER2 Interrupt
    DHT.read11(dht_apin);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("    HUMIDITY    ");
    lcd.setCursor(6,1);
    lcd.print(DHT.humidity);
    lcd.print("%");
    Serial.print(DHT.humidity);
    Serial.println('h');
    delay(4000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("  TEMPERATURE  ");
    lcd.setCursor(5,1);
    lcd.print(DHT.temperature);
    lcd.print("C");
    Serial.print(DHT.temperature);
    Serial.println('t');
    TIM2_EN(); //Disable TIMER2 Interrupt
    delay(4000);
    sensorValue = analogRead(sensorPin); // read the value from the sensor
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("LIGHT INTENSITY");
    lcd.setCursor(7,1);
    lcd.print(sensorValue);
    Serial.print(sensorValue);
    Serial.println('l');
    delay(4000);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print(" CHECKING HEART");
    lcd.setCursor(0,1);
    lcd.print(" RATE NOW......");
    delay(2000);
    lcd.clear();
    start_time = millis();
  }
}

I am trying to run LDR,PULSE AND DHT11 sensor together. DHT11 was not giving out readings along with pulse sensor before so I searched stack exchange and found out this solution.

DHT11 and Pulse sensor incompatibility?

But now the problem is Arduino gets stuck at the line when I disable timer 2 interupt -
TIM2_EN(); //Disable TIMER2 Interrupt

Any solution?

are you sure that TIM2_EN() disables the interrupt? ......  what does TIM2_DIS() do?

I came up with this idea from here.  https://arduino.stackexchange.com/questions/21489/dht11-and-pulse-sensor-incompatibility?noredirect=1&lq=1 The code given in this works with this solution but my code is stuck and it is not even reading values from DHT

If i remove this line the code isn't stuck anymore- TIM2_EN(); //Disable TIMER2 Interrupt....But still Arduino is not able to read values from DHT11.

I do not know, can you explain in detail.

why would an interrupt enable macro be called TIM2_DIS()? ..... why would the interrupt disable macro be called TIM2_EN()?  ....... perhaps you are turning on the interrupt and it causes the program to hang, so the problem may actually be in the ISR

From Github I got this - TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A. What can I do to read values from DHT11 and pulse sensor in the same program?

look at the very first line of your sketch ..... that confirms that you are enabling the interrupt when you thought that you were disabling it ............... now your focus should be on the ISR() to figure out which part is causing the problem ..... perhaps the ISR is too long         ............... also quit asking What can I do to read values from DHT11 and pulse sensor in the same program? and start asking what is causing the failure?

Got the solution, I was accidentally enabling and disabling timer 2 interrupt when actually I was using timer 1 in my program. Now first I am preventing timer 1 interrupts with TIMSK1 = 0 before reading DHT and again enabling timer 1 with TIMSK1 = 0x02 . Thanks #jsotola for telling me to find the failure ! Anyone wants to add anything about interupts ?


text:
Serial communication stops when powered with batteries?
Circuit explanation-

Arduino Uno connected to multiple sensors and to 16 x 2 LCD.
Uno's TX pin to ESP-01 RX pin.
Uno has been programmed to read values from sensors and display them on LCD along with printing them on Serial Monitor.
ESP-01 has been programmed to receive values from Serial Monitor and transmit it to ADAFRUIT MQTT server.

Problem -
However when i am using USB to power the Uno it is successfully displaying data on LCD as well as to Serial Monitor and values are succesfully being send on the MQTT server after being read from Uno's serial.
But when Uno is battery powered, serial communication stops.
I have tried adding 2 decoupling capacitors of 100uF to 12V battery supply. Battery are rechargeable cells.
What could be the issue?

Sure that was done, because your question lacks important information. How much current can your battery supply? How are the Uno and the ESP connected to the supply? Have you investigated, if the serial communication stop is really the problem or just a symptom? For example you may have got a reset due to a dip in the power supply. Maybe try to add a life signal like toggling an LED every half second, or let the led blink once at startup, so that you can see, if there was a reset.

Uno is not resetting that i am sure. Right now I am using a 12v/1Amp adapter to power up the Uno and still problem persists. Is even 1A not enough ?

And how is the ESP connected? It uses a lot of power, especially when connecting to a network. I remember something like up to 600mA, but I'm not sure about that.

ESP is separately powered by another uno for a regulated 3.3v supply. 12V +ve >> Vin of Uno. GND is common for all devices except ESP. Capacitor between 12V +ve and GND of Uno.

how can esp-01 communicate over Serial without common ground?

I think you should not power an ESP from the 3.3V pin of an Uno. According to the datasheet of the LP2985 (the voltage regulator on the Uno Rev3) it can provide only 150mA at max. And as Juraj wrote, if you want circuit to interact in some way, you need a common ground or a circuit with something like an optocoupler. There is no electrical circuit with only 1 wire between the devices.

Thank you guys so much, Juraj and Chris. I commonly grounded the Esp's and Uno's supply and it worked. and what's the technical defination for optocoupler?

You should not power an ESP-01 from any Arduino 3.3v supply. The 3.3V line can't supply enough current. And powering your Arduino with 12V, the 5V regulator will get quite hot if you put out a lot of current (at either 3.3V or 5V. On an Arduino the VIN first gets regulated to 5V, and then the 5V goes through a separate regulator to supply 3.3V. Heat from the 5V regulator is related to VIN voltage and the sum of the currents drawn from the 3.3V lines 5V.) Just get a separate 1A 3.3V switching supply to power the ESP. They're cheap and efficient.

I will put the solution from the comments into an answer.
All devices, that should interact through electrical wires with each other, must have a common ground. Ground is the point, from which the voltage is measured, and the devices need a reference, that is not only valid for themselves, but also valid for the communication partner.
You can think of the following analogy: Image that you and a friend have each one ball, that you are throwing into the sky (a positive height/voltage) and catching it again (zero height/voltage --> ground). While you stand on the parking lot, your friend is standing on a high building. As long as you both only play this with yourself, it is easy for you to throw and catch the ball, because you can easily measure the height of the ball and it will always behave the same. But know imagine, that you want to play together. The height/voltage, that your ball reaches is still positive for you. But from the perspective of your friend it will look, like a large negative height/voltage. How should your friend interpet that and how should he now play with you?

In some electrical circumstances you don't want to connect the grounds of two devices together (maybe because of noise on the ground line). Then you have to achieve galvanic isolation, so no electrical connection between those two. An optocoupler is a device, that can achieve this. Basically it's just an LED and a phototransistor in one casing. From one device you power the LED. Due to the LEDs light, the phototransistor (which is connected to the other device) will become conductive. In combination with a pullup/pulldown resistor on the phototransistor you can have communication without common grounds.


text:
OLED (I2C) and Micro SD card module not working together in Arduino
I am trying to write some data to SD card and read it back to serial monitor as well as display it to the OLED.
Both the sd card and oled work separately but they seem to be interfering with each other when combined. I have used Arduino SD and Adafruit OLED libraries.
Connections from Arduino Uno to Micro SD card module-
5V to SD VCC
GND TO SD GND
PIN 10 TO SD Chip Select
PIN 11 TO SD MOSI
PIN 12 TO SD MISO
PIN 13 TO SD SCK

Connections to OLED-
3.3V to OLED VCC
GND TO OLED GND
A4 TO OLED SDA
A5 TO OLED SCK

Here is the code -
#include <SPI.h>
#include <SD.h>

File myFile;

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

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

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  while(!Serial) {
    ;
  }

  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // CODE GETS STUCK HERE. DISPLAY NEVER INITIALISES
  }
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(29,29);
  display.print("INITIALISING");
  display.display();
  delay(5000);

  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    while (1);
  }
  Serial.println("initialization done.");

  myFile = SD.open("test.txt", FILE_WRITE);

  if (myFile) {
    Serial.print("Writing to test.txt...");
    myFile.println("testing 1, 2, 3.");
    // close the file:
    myFile.close();
    Serial.println("done.");
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }

  display.clearDisplay();

  myFile = SD.open("test.txt");
  if (myFile) {
    Serial.println("test.txt:");
    while (myFile.available()) {
      Serial.write(myFile.read());
      display.setCursor(0,0);
      display.print(myFile.read());
      display.display();
      delay(5000);
    }
    // close the file:
    myFile.close();
  } else {
    // if the file didn't open, print an error:
    Serial.println("error opening test.txt");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

Code gets stuck at OLED initialization as mentiontioned above. If I replace these lines-
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // CODE GETS STUCK HERE. DISPLAY NEVER INITIALISES
    }

To this-
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

I have run I2C scanner code on OLED so the address "0X3C" is correct.
The OLED still doesn't work and SD card initialises but arduino is writing wrong data to TXT file on SD card like this-
teóting 1,à2, ó®

Instead of -
testing 1, 2, 3.

I have also tried using U8G2 library's sketches with SD card in case Arduino was running out of RAM but it still doesn't work. I have also changed SD chip select to Arduino digital pin 4 but still same results.
On browsing and experimenting more,I found MISO OR MOSI PIN of SD maybe interfering with SDA/SCL pins of OLED. Maybe wiring needs to change.
ANY SUGGESTIONS???

I recently had a similar issue with I2C, make sure only one of the modules the I2C pullup resistors.

I am new to this, please can you explain in detail.

Post a link to your both modules.

For OLED - "https://www.amazon.in/Generic-0-96-Display-Module-Arduino/dp/B01GNZEM22/ref=sr_1_10?adgrpid=57784712326&ext_vrnc=hi&gclid=Cj0KCQiAkKnyBRDwARIsALtxe7hvU7JNkEkK9sgmz4vHRgCd4Wk9_GVjZXkkyP9KDhzt6beU8AOcoiwaAtrwEALw_wcB&hvadid=294141455465&hvdev=c&hvlocphy=9061654&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=8620698541412480040&hvtargid=kwd-301353041996&hydadcr=26462_1900820&keywords=oled+128x64&qid=1582009576&sr=8-10"

For SD Card - "https://www.amazon.in/Storage-Memory-Shield-Adapter-Arduino/dp/B00HFQEKI0"

The microSD is not I2C, it uses serial connection. so what I was suggesting is not the case. hopefully someone will help you out.

I just switched to U8G2 Library from Adafruit OLED library and used its u8x8 examples which does not use any RAM. It was a RAM issue. Thanks for looking into it. @ElectronSurf

Glad you fixed it, good luck with your project.

YOU CAN TRY THIS CODE https://forum.arduino.cc/index.php?topic=510106.0 ........

A pullup resistor is needed for I2C, and adding them might fix some errors.

https://github.com/greiman/SSD1306Ascii
use this, it is work with the SD Card module and OLED Display

While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes.


text:
Arduino not detected On El Capitan Public Beta 6
Since I updated to El Capitan Public Beta, my Arduino Uno doesn't show up in the serial devices list.
The System Information utility shows an Arduino connected on the USB port (as 'Communication Device'), but a serial port does not get created at /dev.
The board works on Windows and the previous versions of El Capitan.
The problem persists on beta 6.

Which chip does your Arduino use for the USB interface? Is it the CH340 or the PL2303, or some other variant?  Did any of the answers help resolve your issue? If so, could you accept the answer the answer that helped you?

@Greenonline Unfortunately none of the answers worked for me. I program my Arduino using an Ubuntu machine, though I'd still try any new answers that might come up. Downloading the PL2303 driver did not work for me. And I cannot figure out what chip my Arduino uses.

As noted elsewhere, there have been plenty of problems with the CH340 driver and the OSX El Capitan betas, culminating into the driver flat out not working in the latest beta. This is either a bug with OSX or a bug in the driver. I would lean towards this being a bug in the driver, which hasn't been updated since late 2013.
There are other 3rd party drivers that might work on El Capitan. mac-usb-serial.com is the most reliable looking one that I could find, and it does appear to be actively developed. It does cost money, but it is signed (which the mfg. driver isn't) and it has a test utility you can use before purchasing.
The only other options after that are:

Hope that WCH update their driver (don't hold your breath).
Program using an external programmer
Buy an Arduino not using the CH340

mac-usb-serial.com worked for me in getting a CH34x driver working in 10.11 El Capitan.  It was worth the $8 to put an end to fighting with it.

I have the OS X 10.11 installed and was unable to upload to my Arduino board. I always got stuck with the error code
avrdude stk500_getsync() not in sync resp=0x00

After installing the FTDI driver it didnt't work either. So I figured out Apple provides it's own FTDI driver kernel extension since OS X 10.9, named AppleUSBFTDI.kext. So the AppleUSBFTDI kernel extension interferes with the FTDI driver. An USB port shows up in the Arduino Application, but no communication involving avrdude is possible.
Solution (without modifying or disabling any system security options introduced in 10.11):

Open a terminal
Execute: sudo kextunload /System/Library/Extensions/AppleUSBFTDI.kext/ -> this will unload the Apple FTDI Kernel extension.
Reinstall the FTDI driver
Start the Arduino IDE, select a Com Port, the correct Arduino board
Compile and upload your sketch to the board.

Please note that kextunload will only temporarily unload the module. When your system gets rebooted, you have to do this step again. It's possible to remove the kernel extension, but out of security reasons I don't describe how to do it in this post. If you're familiar with the console, you know how to do this :)

I tried the answer that semm0 mentioned, but the terminal said that I did not have the proper permissions to access that.

My version of OS X 10.11 did not have the driver installed for the FTDI cable that I had.  I downloaded the drivers here (for free): PL2303 Mac OS X Driver Download

Check this https://www.youtube.com/watch?v=0zuRukW7o0A

Reboot and press CMD+R immediately after reboot to enter in Recovery
Mode
Open Terminal from Recovery mode
Run the command csrutil enable --without kext
Reboot
Install driver

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


text:
Receiving partial messages when using VirtualWire and ServoTimer2
I'm writing a project where an Arduino board that is connected to a servo engine receives commands from another Arduino. The possible commands are:

Move 10 degrees
Reset position
Sweep until you're told to stop

My problem is with the sweep-mode, when I get the sweep command, I get into a while loop, that first checks for a sweep-terminator and then sweeps.
} else if (message == sweep) {
  Serial.println("sweep");
  while (msg1 != sweep_term) {
    // set the direction for the servo to move
    if (val == 750){
      val = 2250;
    } else {
      val = 750;
    }

    // move the servo
    myservo.write(val);
    // wait for the servo to move
    delay(15);

    // wait for a message
    if (vw_get_message(buf1, &buflen1)) {
      buf1[buflen1] = '\0';
      msg1 = (char*)buf1;
      memset(buf1,'0',VW_MAX_MESSAGE_LEN);
      Serial.print(buflen1);
      Serial.print(" [sweep] Got: ");
      Serial.println(msg1);
    }
  }
}

For some reason, when I'm in this loop I don't get the sweep terminator message, or I get a part of it. I suspect that the servo is responsible for this, since when I run the same program without myservo.write()s I do receive those terminators.

What do you imagine that memset(buf1,'0',VW_MAX_MESSAGE_LEN); does?

@jwpat7, fills buf1 with zeros? It wasn't intended to be null-terminator or anything else. msg1 is a of type String, not char *

@Quaker You're filling the string with VW_MAX_MESSAGE_LEN zero characters - it's ending up as "000000000....000".  '0' is the character 0 as if you had typed it on your keyboard, not ASCII character code 0 or the NULL character.

Please post the data types for msg1 and buf1.

I suspect that the servo is responsible for this - can you run the code, with the myservo.write() but without the servo physically connected. This will eliminate a possible electrical problem.

@NickGammon, I will try that. msg1 is a String while buf1 is a uint8_t.

@Majenko, I didn't understand your comment. AFAIK there are only two options, 0 as a number and 0 as an ASCII character, what is the 3rd option you suggested?

@Quaker NULL is 0 as a number - used to denote the end of a string.  It's known as the "NULL Terminating Character".  You are using "0 as an ASCII character" when you should be using "0 as a number to denote the NULL terminating character".

@Majenko, no I don't. That wasn't my intention and I clearly stated in the second comment that It wasn't intended to be null-terminator. When I wanted to terminate the string I did it as in buf1[buflen1] = '\0';, while when I used memset() I only wanted to overwrite the whole buffer with a constant character, it could have been 'Z' or anything else.

I simply connected the servo to an external power 5V power source, and everything works perfectly fine. It seems like the servo's resistance was too much for the RF receiver to be able to work as well.

If msg1 is of type char* (as is implied by the cast in msg1 = (char*)buf1;), then it seems to me that that statement will copy the address of buf1 to msg1.  Then, when you fill buf1 with ascii zeroes (ie, characters '0') msg1 ends up being a string of ascii zeroes.
On the other hand, if msg1 is of type String (to go along with your comment about buf1 being of type String) the cast should be unnecessary.
Note, if you don't give the source for the vw_get_message() routine and the declarations for all of the constants and variables used in the code extract, it's unlikely anyone can definitively answer your question.
Note, the while test, msg1 != sweep_term, may not be well-defined on entry to the while loop.  Or, if msg1 is left over from a previous use, you won't enter the loop at all.  Consider writing the loop in the form do { ... } while (msg1 != sweep_term); instead.
Note, if (as said in a comment) buf1 is of type String, then the statement memset(buf1,'0',VW_MAX_MESSAGE_LEN); is a line of code I'd recommend against, because it treats buf1 as a simple array rather than as an object.  (In this case it should make no difference, but it requires some research to be sure of that. [1,2,3,4,5])

It seems likely buf1 is uint8_t judging by this prototype:  uint8_t  vw_get_message (uint8_t *buf, uint8_t *len)

buf1 is indeed a uint8_t and msg1 is a String. I thought that assigning a char * string to a String copies it (as in C#) and not just copying the pointer.

Could it be that the movement of the engine is blocking the RF receiver from receiving the message that is being sent while it's working?

I'm reading online that there are a lot of problems with receiving RF signals while servo is running. When the signal wire of servo is disconnected my code works fluently, but when it is connected and the engine is running - the troubles starts. Any suggestion?

For problem diagnosis, you could try powering different systems (such as Arduino, radio, and servos) with isolated and well-bypassed power supplies, and make all connections with short, soldered-in-place wires.  (See eg seattlerobotics re bypassing.)  Have a 10 or 20 uF cap connected where power goes onto each board, and 0.001 or 0.01 uF caps from each power line to ground, to prevent electrical noise from spreading via power supply connections.  You may need to enclose the radio (except its antenna) in a metal case.

If you can temporarily substitute a wired connection in place of the radio connection, that would allow you to check out your code and perhaps decide if problems are mostly hardware or mostly software.