user76504: I used this simple code to understand the basics of serial communication. This achieves simple communication between the computer and arduino:
String receive_buffer;
void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()>0)  //check for any data received
  {   
      receive_buffer = Serial.readString();  //read received data      
      Serial.print("received data is: ");
      Serial.println(receive_buffer);        //display received data
  }

}

This works. Now, my next idea was to try communicating between two arduinos. I used this code for the reciever arduino.
The sender arduino contains a motor fitted with an encoder, and using the ppr value I  calculate the rpm of the motor. The code for rpm works perfectly. I now want to communicate this data to the receiver.
Wiring: (RX,TX) of sender connected to (TX,RX) of receiver, and GND is made common.
Now, on arduino.cc, it says that Serial.write() can have String as an input. So, I tried typecasting the rpm value (which was int), into a String, and then send that string to the receiver through Serial.write().
float ppr=512.0;
int encpin=3;
volatile long pulsecount=0;
float revs;
float rps;
int rpm;


extern volatile unsigned long timer0_millis;


void setup()
{
  pinMode(encpin,INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
                                        //when pulse is detected
                                           //interrupt triggered,
                                           //function callled  
}
//increments pulse by one
void function(){
  pulsecount+=1;
}


void loop()
{
 revs= pulsecount/ppr ;
 if(millis()>=1000)
  {
    rps= revs;
    rpm=rps*60;
    pulsecount=0; //resets pulsecount
    
    String strrpm= (String)rpm;
   
   
    //Serial.println(rpm);
    Serial.write(strrpm);
   
  
   // Serial.println("string rpm");
    //Serial.println(strrpm);
   
    noInterrupts ();  //resests millis() to 0
    timer0_millis = 0;
    interrupts ();
  }
}

However, I get an error:
43:24: error: no matching function for call to 'HardwareSerial::write(String&)'

The issue is not with typecasting. I tried to simply print strrpm and it worked fine. When tried Serial.write() with a different and simple string, i.e Serial.write("abcdef"); , it still gave the same error.
How then should I should I send my strrpm (string rpm) value to the receiver?

user42015: Serial.write() is meant for sending binary data. So if you want to send a string with it, you need to provide a c-string, not the Arduino implementation of the String class. That's done easily with a member function of that class:
Serial.write(strrpm.c_str());

That compiles successfully for me.
Though you should not do it like this. The String class is generally bad on small microcontrollers, especially on the AVR microcontrollers with little memory (like Uno, Nano, Mega, ...), because it causes memory fragmentation (see Majenkos "The Evils of Arduino Strings").
Instead you should just use the corresponding print() functions of the Serial class. They are made for sending human readable strings. No need to first build up a String object. Just do
Serial.println(rpm);

And it will do the string conversion itself without using the String class.

Besides that I have some notes on your code:

The way you use millis() is a bit weird. There is no need to actually reset the millis() value itself. Normally you would hold a timestamp in a variable and then only calculate the difference between millis() and the timestamp. That is also overflow safe. Like this
  unsigned long timestamp = 0;

  ...
  if(millis()-timestamp >= 1000){
      ...
      timestamp+=1000;
  }

That doesn't use an extern variable, it is not resetting the millis() counter (which might mess with other things too, that rely on it) and is somewhat the standard way to do it.

You are using an atomic section for resetting the millis() counter, but not for accessing pulsecount. That is actually the place, where you absolutely need this. pulsecount is of type long, so it will need many instructions to do the calculation for revs. The your interrupt service routine can easily mess with the data in that moment, resulting in garbled data. Move  the calculation into the if statement and use an atomic section like with the millis() counter to read it into a local variable then you can do the calculations. That will keep the time, where interrupts are turned off very short. You can also - instead of turning all interrupts off - just detach the pin interrupt for that time, so that other things are not affected. Like this code:
  void loop(){
      if(millis()-timestamp > 1000){
           // deactivate our pin interrupt, so it cannot mess with the data
           detachInterrupt(digitalPinToInterrupt(encpin));
           // copy pulsecount to local variable for further calculation
           long local_pulsecount = pulsecount;
           // reactivate our pin interrupt
           attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
           // Do calculation and print the value
           ...
           timestamp += 1000;
       }
   }




76504: <p>I used this simple code to understand the basics of serial communication. This achieves simple communication between the computer and arduino:</p>
<pre><code>String receive_buffer;
void setup() {
  Serial.begin(9600);
}

void loop() {
  if(Serial.available()&gt;0)  //check for any data received
  {   
      receive_buffer = Serial.readString();  //read received data      
      Serial.print(&quot;received data is: &quot;);
      Serial.println(receive_buffer);        //display received data
  }

}
</code></pre>
<p>This works. Now, my next idea was to try communicating between two arduinos. I used this code for the reciever arduino.</p>
<p>The sender arduino contains a motor fitted with an encoder, and using the ppr value I  calculate the rpm of the motor. The code for rpm works perfectly. I now want to communicate this data to the receiver.</p>
<p><strong>Wiring</strong>: (RX,TX) of sender connected to (TX,RX) of receiver, and <code>GND</code> is made common.</p>
<p>Now, on arduino.cc, it says that Serial.write() can have String as an input. So, I tried typecasting the rpm value (which was int), into a String, and then send that string to the receiver through Serial.write().</p>
<pre><code>float ppr=512.0;
int encpin=3;
volatile long pulsecount=0;
float revs;
float rps;
int rpm;


extern volatile unsigned long timer0_millis;


void setup()
{
  pinMode(encpin,INPUT_PULLUP);
  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
                                        //when pulse is detected
                                           //interrupt triggered,
                                           //function callled  
}
//increments pulse by one
void function(){
  pulsecount+=1;
}


void loop()
{
 revs= pulsecount/ppr ;
 if(millis()&gt;=1000)
  {
    rps= revs;
    rpm=rps*60;
    pulsecount=0; //resets pulsecount
    
    String strrpm= (String)rpm;
   
   
    //Serial.println(rpm);
    Serial.write(strrpm);
   
  
   // Serial.println(&quot;string rpm&quot;);
    //Serial.println(strrpm);
   
    noInterrupts ();  //resests millis() to 0
    timer0_millis = 0;
    interrupts ();
  }
}
</code></pre>
<p>However, I get an error:</p>
<pre><code>43:24: error: no matching function for call to 'HardwareSerial::write(String&amp;)'
</code></pre>
<p>The issue is not with typecasting. I tried to simply print strrpm and it worked fine. When tried Serial.write() with a different and simple string, i.e <code>Serial.write(&quot;abcdef&quot;);</code> , it still gave the same error.</p>
<p><strong>How then should I should I send my strrpm (string rpm) value to the receiver?</strong></p>
 42015: <p><code>Serial.write()</code> is meant for sending binary data. So if you want to send a string with it, you need to provide a c-string, not the Arduino implementation of the <code>String</code> class. That's done easily with a member function of that class:</p>
<pre><code>Serial.write(strrpm.c_str());
</code></pre>
<p>That compiles successfully for me.</p>
<p>Though you should not do it like this. The <code>String</code> class is generally bad on small microcontrollers, especially on the AVR microcontrollers with little memory (like Uno, Nano, Mega, ...), because it causes memory fragmentation (see <a href="https://hackingmajenkoblog.wordpress.com/2016/02/04/the-evils-of-arduino-strings/" rel="nofollow noreferrer">Majenkos &quot;The Evils of Arduino Strings&quot;</a>).</p>
<p>Instead you should just use the corresponding <code>print()</code> functions of the <code>Serial</code> class. They are made for sending human readable strings. No need to first build up a <code>String</code> object. Just do</p>
<pre><code>Serial.println(rpm);
</code></pre>
<p>And it will do the string conversion itself without using the <code>String</code> class.</p>
<hr />
<p>Besides that I have some notes on your code:</p>
<ul>
<li><p>The way you use <code>millis()</code> is a bit weird. There is no need to actually reset the <code>millis()</code> value itself. Normally you would hold a timestamp in a variable and then only calculate the difference between <code>millis()</code> and the timestamp. That is also overflow safe. Like this</p>
<pre><code>  unsigned long timestamp = 0;

  ...
  if(millis()-timestamp &gt;= 1000){
      ...
      timestamp+=1000;
  }
</code></pre>
<p>That doesn't use an extern variable, it is not resetting the <code>millis()</code> counter (which might mess with other things too, that rely on it) and is somewhat the standard way to do it.</p>
</li>
<li><p>You are using an atomic section for resetting the <code>millis()</code> counter, but not for accessing <code>pulsecount</code>. That is actually the place, where you absolutely need this. <code>pulsecount</code> is of type <code>long</code>, so it will need many instructions to do the calculation for <code>revs</code>. The your interrupt service routine can easily mess with the data in that moment, resulting in garbled data. Move  the calculation into the if statement and use an atomic section like with the <code>millis()</code> counter to read it into a local variable then you can do the calculations. That will keep the time, where interrupts are turned off very short. You can also - instead of turning all interrupts off - just detach the pin interrupt for that time, so that other things are not affected. Like this code:</p>
<pre><code>  void loop(){
      if(millis()-timestamp &gt; 1000){
           // deactivate our pin interrupt, so it cannot mess with the data
           detachInterrupt(digitalPinToInterrupt(encpin));
           // copy pulsecount to local variable for further calculation
           long local_pulsecount = pulsecount;
           // reactivate our pin interrupt
           attachInterrupt(digitalPinToInterrupt(encpin),function,RISING);
           // Do calculation and print the value
           ...
           timestamp += 1000;
       }
   }
</code></pre>
</li>
</ul>
