body:
I am using an Arduino Uno board to compute the angles of my system (robotic arm). The angles are actually 10 bit values (0 to 1023) from the ADC, using the full range of the ADC. I am only going to be operating in the 1st quadrant (0 to 90 deg), where both sines and cosines are positive, so there is no problem with negative numbers. My doubts can be expressed in 3 questions:

1. What are the different ways to compute these trigonometric functions on Arduino?

2. What is the fastest way to do the same?

3. There are the sin() and cos() functions in the Arduino IDE, but how does the Arduino actually calculate them (as in do they use look-up tables, or approximations etc.)? They seem like an obvious solution, but I would like to know their actual implementation before I try them out.

PS: I am open to both standard coding on the Arduino IDE and assembly coding, as well as any other options not mentioned. Also I have no problems with errors and approximations, which are inevitable for a digital system; however if possible it would be good to mention the extent of possible errors

title: Different ways (and the fastest) to compute sines (and cosines) in Arduino

Answers: 10

body:
generally, look-up table > approximation -> calculation. ram > flash. integer > fixed point > floating point. pre-calclation > real time calculation. mirroring (sine to cosine or cosine to sine) vs. actual calculation / look-up....

each has its pluses and minuses.

you can make all sorts of combinations to see which works best for your application.

edit: I did a quick checking. using 8-bit integer output, calculating 1024 sin values with look-up table takes 0.6ms, and 133ms with floaters, or 200x slower.

body:
The two basic methods are mathematical calculation (with polynomials) and lookup tables.

The Arduino's math library (libm, part of avr-libc) uses the former. It is optimised for the AVR in that it is written with 100% assembly language, and as such is almost impossible to follow what it's doing (there's zero comments as well). Rest assured though it will be the most optimised pure-float implementation brains far superior to ours could come up with.

However the key there is *float*. Anything on the Arduino involving floating point is going to be heavyweight by comparison to pure integer, and since you are only requesting integers between 0 and 90 degrees a simple lookup table is by far the simplest and most efficient method.

A table of 91 values will give you everything from 0 to 90 inclusive. However if you make that a table of floating point values between 0.0 and 1.0 you still then have the inefficiency of working with floats (granted not as inefficient as calculating `sin` with floats), so storing a fixed point value instead would be far more efficient.

That may be as simple as storing the value multiplied by 1000, so you have between 0 and 1000 instead of between 0.0 and 1.0 (for instance sin(30) would be stored as 500 instead of 0.5). More efficient would be to store the values as, for instance, a Q16 value where each value (bit) represents 1/65536th of 1.0. These Q16 values (and the related Q15, Q1.15, etc) are more efficient to work with since you have powers-of-two which computers love to work with instead of powers-of-ten which they hate working with.

Don't forget as well that the `sin()` function expects radians, so you first have to convert your integer degrees into a floating point radians value, making the use of `sin()` even more inefficient compared to a lookup table that can work directly with the integer degrees value.

A combination of the two scenarios, though, is possible. *Linear interpolation* will allow you to get an approximation of a floating point angle between two integers. It's as simple as working out how far between two points in the lookup table you are and creating a weighted average based on that distance of the two values. For instance if you are at 23.6 degrees you take `(sintable[23] * (1-0.6)) + (sintable[24] * 0.6)`. Basically your sine wave becomes a series of discrete points joined together by straight lines.  You trade accuracy for speed.

body:
You could create a couple of functions that uses linear approximation to determine the sin() and cos() of a particular angle.

I am thinking something like this:
[![linear approximation][2]][2]
For each I have broken the graphical representation of sin() and cos() into 3 sections and have done a linear approximation of that section.

Your function would ideally first check that the range of the angel is between 0 and 90.
Then it would use an `ifelse` statement to determine what of the 3 sections it belongs and then does the corresponding linear calculation (ie `output = mX + c`)

  [1]: http://stackoverflow.com/a/2088589/6075112
  [2]: https://i.stack.imgur.com/4WuNU.gif

body:
I looked for other people that had approximated cos() and sin() and I came across this answer:

[dtb's answer to "Fast Sin/Cos using a pre computed translation array"][1]

Basically he computed that the math.sin() function from the math library was faster than using a look-up table of values. But from what I can tell, this was computed on a PC.

Arduino has a [math library][2] included that can calculate sin() and cos().

  [1]: https://stackoverflow.com/a/2088589/6075112
  [2]: https://www.arduino.cc/en/Reference/MathHeader

body: A lookup table will be the fastest way to find sines. And if you're comfortable computing with fixed-point numbers (integers whose binary-point is somewhere other than to the right of bit-0), your further calculations with the sines will be much faster as well. That table can then be a table of words, possibly in Flash to save RAM space. Note that in your math you may need to use longs for large intermediate results.

body:
There are some good answers here but I wanted to add a method which hasn't been mentioned yet, one very well suited to computing trigonometric functions on embedded systems, and that's the CORDIC technique
[Wiki Entry Here][1] It can compute trig functions using only shifts and adds and a small look-up table.

Here's a crude example in C. In effect, it implements the C libraries' atan2() function using CORDIC (i.e. find an angle given two orthogonal components.) It uses floating point, but can be adapted for use with fixed-point arithmetic.

    /*
     * Simple example of using the CORDIC algorithm.
     */

    #include <stdio.h>
    #include <math.h>

    #define CORDIC_TABLE_SIZE  16

    double cordic_table[CORDIC_TABLE_SIZE];

    void init_table(void);
    double angle(double I, double Q);

    /*
     * Given a sine and cosine component of an
     * angle, compute the angle using the CORIDC
     * algoritm.
     */
    double angle(double I, double Q)
    {
        int L;
        double K = 1;
        double angle_acc = 0;
        double tmp_I;

        if (I < 0) {
            /* rotate by an initial +/- 90 degrees */
            tmp_I = I;
            if (Q > 0.0) {
                I = Q;           /* subtract 90 degrees */
                Q = -tmp_I;
                angle_acc = -90;
            } else {
                I = -Q;          /* add 90 degrees */
                Q = tmp_I;
                angle_acc = 90;
            }
        } else {
            angle_acc = 0;
        }

        /* rotate using "1 + jK" factors */
        for (L = 0, K = 1; L <= CORDIC_TABLE_SIZE; L++) {
            tmp_I = I;
            if (Q >= 0.0) {
                /* angle is positive: do negative roation */
                I += Q * K;
                Q -= tmp_I * K;
                angle_acc -= cordic_table[L];
            } else {
                /* angle is negative: do positive rotation */
                I -= Q * K;
                Q += tmp_I * K;
                angle_acc += cordic_table[L];
            }
            K /= 2.0;
        }
        return -angle_acc;
    }

    void init_table(void)
    {
        int i;
        double K = 1;

        for (i = 0; i < CORDIC_TABLE_SIZE; i++) {
            cordic_table[i] = 180 * atan(K) / M_PI;
            K /= 2.0;
        }
    }
    int main(int argc, char **argv)
    {
        double I, Q, A, Ar, R, Ac;

        init_table();

        printf("# Angle,    CORDIC Angle,  Error\n");
        for (A = 0; A < 90.0; A += 0.5) {

            Ar = A * M_PI / 180; /* convert to radians for C's sin & cos fn's */

            R = 5;  // Arbitrary radius

            I = R * cos(Ar);
            Q = R * sin(Ar);

            Ac = angle(I, Q);
            printf("�, �,   .4e\n", A, Ac, Ac-A);
        }
        return 0;
    }

But try the native Arduino trig functions first - they might be fast enough anyway.

  [1]: https://en.wikipedia.org/wiki/CORDIC

body:
I have been playing a bit with computing sines and cosines on the
Arduino using fixed-point polynomial approximations. Here are my
measurements of average execution time and worst case error, compared
with the standard `cos()` and `sin()` from avr-libc:

    function    max error   cycles   time
    -----------------------------------------
    cos_fix()   9.53e-5     108.25    6.77 µs
    sin_fix()   9.53e-5     110.25    6.89 µs
    cos()       2.98e-8     1720.8   107.5 µs
    sin()       2.98e-8     1725.1   107.8 µs

It's based on a 6th degree polynomial computed with only
4 multiplications. The multiplications themselves are done in
assembly, as I found that gcc implemented them inefficiently. The angles
are expressed as `uint16_t` in units of 1/65536 of a revolution, which
makes the arithmetic of angles naturally work modulo one revolution.

If you think this can suit your bill, here is the code: [Fixed-point
trigonometry](https://wiki.logre.eu/index.php/Trigonométrie_en_virgule_fixe).
Sorry, I still did not translate this page, which is in French, but you
can understand the equations, and the code (variable names, comments...)
is in English.

------------------------------------------------------------------------

**Edit**: Since the server seems to have vanished, here is some info on
the approximations I found.

I wanted to write angles in binary fixed-point, in units of quadrants
(or, equivalently, in turns). And I also wanted to use an even
polynomial, as these are more efficient to compute than arbitrary
polynomials. In other words, I wanted a polynomial P() such that

cos(π/2 x) ≈ P(x2)  for x ∈ [0,1]

I also required the approximation to be exact at both ends of the
interval, to ensure that cos(0) = 1 and
cos(π/2) = 0. These constraints led to the form

P(u) = (1 − u)(1 + uQ(u))

where Q() is an arbitrary polynomial.

Next, I searched for the best solution as a function of the degree of
Q() and found this:

            Q(u)             │ degree of P(x²) │ max error
    ─────────────────────────┼─────────────────┼──────────
              0              │         2       │  5.60e-2
           −0.224            │         4       │  9.20e-4
    −0.2335216 + 0.0190963 u │         6       │  9.20e-6

The choice among the solutions above is a speed/accuracy trade-off. The
third solution gives more accuracy than achievable with 16-bits, and
it's the one I chose for the 16-bit implementation.

body:
I had a simillar question to OP. I wanted to make a LUT table to calculate the first quadrant of the sine function as unsigned 16 bit integers starting from 0x8000 to 0xffff. And i ended up writing this for fun and profit. Note: This would work more efficiently if i used 'if' statements. Also it's not very accurate, but would be accurate enough for a sine wave in a sound synthesiser

    void sin_lut_ctor(){

    //Make a Look Up Table for 511 terms of the sine function.
    //Plugin in some polynomials to do some magic
    //and you get an aproximation for sines up to π/2.
    //

    //All sines yonder π/2 can be derived with math

    const uint16_t uLut_d = 0x0200; //maximum LUT depth for π/2 terms.
    uint16_t uLut_0[uLut_d];        //The LUT itself.
    //Put the 2 above before your void setup() as global variables.
    //This coefficients will only work for uLut_d = 511.

    uint16_t arna_poly_0 = 0x000a; // 11
    uint16_t arna_poly_1 = 0x0001; // 1
    uint16_t arna_poly_2 = 0x0007; // 7
    uint16_t arna_poly_3 = 0x0001; // 1   Precalculated Polynomials
    uint16_t arna_poly_4 = 0x0001; // 1
    uint16_t arna_poly_5 = 0x0007; // 7
    uint16_t arna_poly_6 = 0x0002; // 2
    uint16_t arna_poly_7 = 0x0001; // 1

    uint16_t Imm_UI_0 = 0x0001;              //  Itterator
    uint16_t Imm_UI_1 = 0x007c;              //  An incrementor that decreases in time

    uint16_t Imm_UI_2 = 0x0000;              //
    uint16_t Imm_UI_3 = 0x0000;              //
    uint16_t Imm_UI_4 = 0x0000;              //
    uint16_t Imm_UI_5 = 0x0000;              //
    uint16_t Imm_UI_6 = 0x0000;              //  Temporary variables
    uint16_t Imm_UI_7 = 0x0000;              //
    uint16_t Imm_UI_8 = 0x0000;              //
    uint16_t Imm_UI_9 = 0x0000;              //
    uint16_t Imm_UI_A = 0x0000;
    uint16_t Imm_UI_B = 0x0000;

    uint16_t Imm_UI_A = uLut_d - 0x0001;     //  510

    uLut_0[0x0000] = 0x8000;        //Assume that the middle point is 32768 (0x8000 hex)
    while (Imm_UI_0 < Imm_UI_A) //Construct a quarter of the sine table
      {
    Imm_UI_2++;                                   //Increase temporary variable by 1

    Imm_UI_B = Imm_UI_2 / arna_coeff_0;           //Divide it with the first coefficient (note: integer division)
    Imm_UI_3 += Imm_UI_B;                         //Increase the next temporary value if the first one has increased up to the 1st coefficient
    Imm_UI_1 -= Imm_UI_B;                         //Decrease the incrementor if this is the case
    Imm_UI_2 *= 0x001 - Imm_UI_B;                 //Set the first temporary variable back to 0

    Imm_UI_B = Imm_UI_3 / arna_poly_1;           //Do the same thing as before with the next set of temporary variables
    Imm_UI_4 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_3 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_4 / arna_poly_2;           //And again... and again... you get the idea.
    Imm_UI_5 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_4 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_5 / arna_poly_3;
    Imm_UI_6 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_5 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_6 / arna_poly_4;
    Imm_UI_7 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_6 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_7 / arna_poly_5;
    Imm_UI_8 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_7 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_8 / arna_poly_6;
    Imm_UI_9 += Imm_UI_B;
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_8 *= 0x0001 - Imm_UI_B;

    Imm_UI_B = Imm_UI_9 / arna_poly_7          //the last set won't need to increment a next variable so skip the step where you would increase it.
    Imm_UI_1 -= Imm_UI_B;
    Imm_UI_9 *= 1 - Imm_UI_B;

    uLut_0[Imm_UI_0] = (uLut_0[Imm_UI_0 - 0x0001] + Imm_UI_1); //Set the current value as the previous one increased by our incrementor
    Imm_UI_0++;              //Increase the itterator
      }
      uLut_0[Imm_UI_A] = 0xffff; //Lastly, set the last value to 0xffff

      //And there you have it. A sine table with only one if statement (a while loop)
    }

Now to get back the values, use this function.It accepts a value from 0x0000 to 0x0800 and returns the appropriate value from the LUT

    uint16_t lu_sin(uint16_t lu_val0)
    {
      //Get a value from 0x0000 to 0x0800. Return an appropriate sin(value)
      Imm_UI_0 = lu_val0/0x0200; //determine quadrant
      Imm_UI_1 = lu_val0%0x0200; //Get which value
      if (Imm_UI_0 == 0x0000)
      {
        return uLut_0[Imm_UI_1];
      }
      if (Imm_UI_0 == 0x0001)
      {
        return uLut_0[0x01ff - Imm_UI_1];
      }
      if (Imm_UI_0 == 0x0002)
      {
        return 0xffff - uLut_0[Imm_UI_1];
      }
      if (Imm_UI_0 == 0x0003)
      {
        return 0xffff - uLut_0[0x01ff - Imm_UI_1];
      }
    }// I'm using if statements here but similarly to the above code block,
     //you can do without. just with integer divisions and modulos

Remember, this is not the most efficient approach to this task, i just couldn't figure out how to make taylor series to give out results in the appropriate range.

body:
Just for the fun of it, and to prove it can be done, I finished an AVR assembly routine to calculate sin(x) results in 24 bits (3 bytes) with one bit of error.  The input angle is in degrees with one decimal digit, from 000 to 900 (0~90.0) for the first quadrant only.  It uses less than 210 AVR instructions and runs on average of 212 microseconds, varying from 211us (angle=001) to 213us (angle=899).

It took several days to do it all, more than 10 days (free hours) just thinking about the best algorithm for the calculation, considering the AVR microcontroller, no floating point, eliminating all possible divisions. What took more time was to make the right step-up values for integers, to have good precision it needs to step-up values of 1e-8 to binary integers 2^28 or more.  Once all the errors culprits of precision and rounding up were found, increased their calculation resolution by extra 2^8 or 2^16, the best results were met.  I first simulated all the calculations on Excel taking care of having all values as Int(x) or Round(x,0) to represent exactly the AVR core processing.

For example, in the algorithm the angle must be in Radians, the input is in Degrees to facilitate for the user.  To convert Degrees to Radians the trivial formula is rad=degrees*PI/180, it seems nice and easy, but it is not, PI is an infinite number - if using few digits it will create errors at the output, division by 180 requires AVR bit manipulation since it has no division instruction, and more than that, the result would require floating point since involves numbers far below integer 1. For example, Radian of 1° (degree) is 0.017453293. Since PI and 180 are constants, why not reverse this thing for simple multiplication?  PI/180 = 0.017453293, multiply it by 2^32 and it results as a constant 74961320 (0x0477D1A8), multiply this number by your angle in degrees, lets say 900 for 90° and shift it 4 bits right (÷16) to obtain 4216574250 (0xFB53D12A), that is the radians of the 90° with 2^28 expansion, fit in 4 bytes, without a single division (except the 4 bit shift right). In a way, the error included in such trick is smaller than 2^-27.

So, all further calculations need to remember it is 2^28 higher and taken care of it. You need to divide the on-the-go results by 16, 256 or even 65536 just to avoid it use unnecessary growing hunger bytes that would not help resolution.  That was a painstaking job, just finding the minimum quantity of bits in each calculation results, keeping the results precision around 24 bits. Each one of the several calculations where done in try/error with higher or lower bits count in the Excel flow, watching the overall quantity of error bits at the result in a graph showing 0-90° with a macro running the code 900 times, once per tenth of a degree. That "visual" Excel approach was a tool I created, helped a lot to find the best solution for every single part of the code.

For example, rounding up this particular calculation result 13248737.51 to 13248738 or just lose the "0.51" decimals, how much it will affect the final result precision for all the 900 input angles (00.1 ~ 90.0) tests?

I was able to keep the animal contained within 32 bits (4 bytes) on every calculation, and ended up with the magic to obtain precision within 23 bits of the result. When checking the whole 3 bytes of the result, the error is ±1 LSB, outstanding.

The user may grab one, two or three bytes from the result for its own requirements of precision.  Of course, if just one byte is enough I would recommend to use a single 256 bytes sin table and use AVR 'LPM' instruction to grab it.

Once I had the Excel sequence running smooth and neat, the final translation from Excel to AVR assembly took less than 2 hours, as usual you should think more first, work less later.

At that time I was able to squeeze yet more and reduce registers usage. The actual (not final) code uses around 205 instructions (~410 bytes), runs a sin(x) calculation in average of 212us, clock at 16MHz. At that speed it can calculate 4700+ sin(x) per second. Not being important, but it can run a precise sinewave up to 4700Hz with 23 bits of precision and resolution, without any lookup tables.

The base algorithm is based on Taylor series for sin(x), but modified a lot to fit my intentions with the AVR microcontroller and precision in mind.

Even that using a 2700 bytes table (900 entries * 3 bytes) would be speed attractive, what is the fun or learning experience on that?  Of course, CORDIC approach was also considered, maybe later, the point here is to squeeze Taylor into the AVR core and take water from a dry rock.

I wonder if Arduino "sin(78.9°)" can run Processing (C++) with 23 bits of precision in less than 212us and the necessary code smaller than 205 instructions. May be if C++ uses CORDIC.  Arduino sketches can import assembly code.

Makes no sense to post the code here, later I will edit this post to include a weblink to it, possibly on my blog at [this url][1]. The blog is mostly in portuguese.

This hobby-no-money venture was interesting, pushing the limits of the AVR engine of almost 16MIPS at 16MHz, without division instruction, multiplication only in 8x8 bits.  It allows to calculate sin(x), cos(x) [=sin(900-x)] and tan(x) [=sin(x)/sin(900-x)].

Above it all, this helped to keep my 63 years old brain polished and oiled. When teenagers say the 'old people' know sh*nothing about technology, I answer "think again, who do you think created the bases for everything you enjoy today?".

Cheers

  [1]: http://www.ustr.net/blog/xblog/

body:
As others have mentioned lookup tables are the way to go if you want speed. I've recently been investigating computation of trig functions on an ATtiny85 for use of fast vector averages (wind in my case). There's always trade off's...for me I only needed 1 deg angular resolution so a lookup table of 360 int's (scaling -32767 to 32767, only working with int's) was the best way to go. Retrieving the sine is just a matter of supplying an index 0-359...so very fast! Some numbers from my tests:

FLASH lookup time (us): 0.99 (table stored using PROGMEM)

RAM lookup time (us): 0.69 (table in RAM)

Lib time (us): 122.31 (Using Arduino Lib)

Note these are averages across a 360 point sample for each. Testing was done on a nano.


body:
I found this useful website explaining for to configure and implement the TWI for mega328p, but what I found not so obvious is that in the website they set TWEN in every function, while in the datasheet C code example, they only set it in START and STOP functions.

I also find another style in Arduino Wire library, that they implement more easier functions for starting and ending the module.

This is the website, could anyone take a look and tell me if setting TWEN in each function is necessary?

Also, is it necessary to check for TWINT after sending STOP command?

[http://www.embedds.com/programming-avr-i2c-interface/][1]

Regards,

  [1]: http://www.embedds.com/programming-avr-i2c-interface/

title: Is setting AVR TWCR for mega328p TWEN in each function necessary?

Answers: 1

body:
The big difference is interrupt driven or busy wait implementation of the TWI hardware module protocol. Enabling interrupts is necessary in an interrupt driven implementation while busy wait should not enable interrupts.

A busy wait implementation is much simpler but it cannot be asynchronous. An interrupt driven implementation can be asynchronous and even power down the rest of the MCU during the TWI communication. It should be noted that the Arduino Wire class is interrupt driven but synchronous.

Cheers!


body:
I am trying to learn internet of things with smart home. I will connect an ESP8266 and an Arduino with the IBM Bluemix server to control a circuit from a public IP.

I want to start with the local network for now. I have gone through a couple of links which seem like a great start http://allaboutee.com/2014/12/30/esp8266-and-arduino-webserver/

They explain how it works, and have source code but no circuit diagram. How should I connect the ESP8266 with Arduino for this example ?

[![enter image description here][1]][1]

[![enter image description here][2]][2]

 #include <SoftwareSerial.h>

 const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
 const byte txPin = 3; // Wire this to Rx Pin of ESP8266

 // We'll use a software serial interface to connect to ESP8266
 SoftwareSerial esp8266(rxPin,txPin);

 void setup() {
   Serial.begin(9600);
   esp8266.begin(9600);
   delay(1000);
 }

 void loop() {
   Serial.println("Sending an AT commands");
   esp8266.println("AT");
   delay(30);
   while(esp8266.available()) {
  String data = esp8266.readStringUntil('\n');
  Serial.println("Got response from esp8266: " + data);
   }
 }

  [1]: https://i.stack.imgur.com/Ldlol.jpg
  [2]: https://i.stack.imgur.com/T2GLD.jpg

title: How does ESP8266 work as web server with Arduino?

Answers: 1

body:
The exact same way as any other ESP8266 example. The fact that you are using it as a web server doesn't change how you wire it.

For that specific code snippet it even tells you in the comments:

    // make RX Arduino line is pin 2, make TX Arduino line is pin 3.
    // This means that you need to connect the TX line from the esp to the Arduino's pin 2
    // and the RX line from the esp to the Arduino's pin 3


body:
I was actually quite impressed how easily Blynk gets connected to Arduino. So I had a doubt how does Arduino WiFi Shield allow Arduino Uno to connect to blynk ? And my second doubt is how can I use the ESP boards to connect to blynk using Windows10 ( for steps ) ?
Thank You.

title: How does Arduino WiFi Shield connect to Blynk and How can I use ESP Module to connect to blynk?

Answers: 1

body:
> how does Arduino WiFi Shield allow Arduino Uno to connect to blynk

Blynk is just a web service. The WiFi shield connects your board to the internet and sends data to that web service. The Blynk app is just an interface to that web service.

> how can I use the ESP boards to connect to blynk using Windows10?

That makes no sense. You can connect an MCU to Blynk through something like an ESP8266 board (or program the ESP8266 board directly to communicate with Blynk). It is merely a network interface.

Windows 10 is not an MCU, and you already have an internet connection on it. If you want to communicate with Blynk from Windows 10 I suggest you look at the documents to see if there is an API you can use from your own programs, or a web interface you can view in your browser of choice.

Windows 10 and ESP8266 are two completely alien concepts.


body:
Is it possible to sandwich an XBee shield between Arduino Mega and Ramps 1.4 without damaging any of the boards or lose of Ramps functionality ?

I am not trying to make a 3D printer it is rather a completely different project and I am afraid of burning my XBee or losing some functionality of ramps.

Since XBee shield has the form factor of Arduino UNO I had to 3D print the rest of the shield and use some connectors to completely cover the Mega.

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/QKUMY.jpg

title: Arduino Mega + XBee Shield + RAMPS 1.4 Is it possible?

Answers: 2

body:
Yes, it would seem like folks on the RepRap forums have gotten this to work with the following setup that should work in general:

> Attach the XBee shield to the RAMPS board by attaching 4 pins on AUX-1 (namely, 5V, Gnd, D1 and D0) to the 5V, Gnd, Rx and Tx pins on the XBee Shield
>
> Switch the UART / DLINE switch on the XBee Shield to UART

Source: [RepRap Forum: Printing completely wirelessly - can it be done?][1]

This [forum thread][2] may also be useful.

  [1]: http://forums.reprap.org/read.php?219,105307
  [2]: http://forums.reprap.org/read.php?219,455864

body:
Yes, and the answer is really simple.  You need to extend the connectors between the xbee shield and the ramps shield.  Either by adding another layer of the through pin connectors you have or by resoldering some longer ones on the RAMPS board.

You might have an issue with the RF signal, sticking that much metal near the xbee board might cause problems, but I think you can get external aerials for them, if that becomes an issue.


body:
I'm making a project, but my arduino pro micro is just slightly too big to fit in it's case.

What would happen if I cut off the pin holes that I don't need? Would it still work? Or would it be ruined?

title: Can I cut the pin holes off of my Arduino board?

Answers: 4

body:
I guess that one *could* cut (or hone down) parts of the PCB. Obviosly this process devoids the warranty and there is the risk of damaging either the board or some components on it (i.e. by holding or clamping it during the process).

I would not expect any other wiring besides those connecting the pins to run in this part of the PCB. The reference layout (see [board layout](https://www.arduino.cc/en/Main/arduinoBoardMicro#documentation) and using [Eagle (free version)](http://www.autodesk.com/products/eagle/free-download)) - if the clones follow that layout - confirms that there are no other traces there. So it is mostly important to not cut any other traces and remove any chippings after the cutting to avoid short circuits.

If in doubt buy two or three boards ;) to try and repeat the process.

body:
This is a bad ideas:

 - the PCB is made of fiber glass which, when broken, cut or filed, produces a very fine powder; any powder you might breath in during the process wil stay in lungs for a very long time, in the order of decades

 - the risk of cracking traces running close to the are of cut, even if they are not directly being cut, is pretty high; the copper traces rely on the fiberglass rigidity, but a crack in the fiberglass propagating under the traces is welcoming a broken trace

Go for a different case, if that's not a viable option go for a barebone arduino. If that is also a non viable option consider the idea of producing a few custom PCBs: they are not that expensive!

body:
Rather than trying to modify the board (which I think is a bad idea) why not use a `Pro Mini`.

These are smaller (and cheaper), and almost identical in function, apart from the USB interface. You do need a serial interface (or ICSP) to program.

body: You could use a Pro Mini as Milliways suggested, but you don't necessarily need a USB interface to programme it.  You can use your Arduino UNO to directly programme the Arduino Pro Mini.


body:
I bought a very old oscilloscope and although it works, I have my doubts about refreshing the screen (the electron beam fades away very slowly or is not showing up consistently across the screen).

I tested a bit with `digitalWrite` and `anlogWrite`, but this only sends either 0 or 5V out. Is there a way to make a preferably sine or triangle wave of 0 to 5V or -5 to +5V... I guess the Arduino should be capable of it, but so far I only get 0V or 5V out, nothing in between.

According to [lesson 8][1] I should get a variable voltage of 0-5V on a pin with `analogWrite`, but all I get is 0 or 5V.

  [1]: http://www.toptechboy.com/arduino/lesson-8-writing-analog-voltages-in-arduino/

For what I see:

1. PWM gives with `analogWrite` a pulse signal of 0V or 5V with a duty cycle.
2. non PWM pins give either 0V or 5V (`analogWrite` of 0-127 appr: 0V, >127: 5V).

title: Testing an oscilloscope with my Arduino

Answers: 2

body:
You can convert the PWM output of `analogWrite()` into an (approximate) analog voltage by adding a low-pass filter. That is, a resistor in series followed by a capacitor to ground.

The values to choose depend on the frequency response you want.

* [RC Filter Calculator](http://sim.okawa-denshi.jp/en/CRtool.php) (second section).

For anything more complex or accurate you will need a DAC. I often use the MCP4822 SPI DAC chip.

body:
a few ways:

1) you can generate a square wave of a known frequency to test the time base of the scope;

2) you can generate an analog signal to test for the vertical. that can be done via pwm or dds.


body:
I am running out of memory on my Arduino due to the libraries I am using. After I have included all the libraries I need then there is very little in the way of free memory for my own code.

If hook up some external RAM to the Arduino, is there a way I can make existing libraries use the external RAM rather than the SRAM on the arduino or will I need to alter the code in the library to do it.

If I have to modify the code is that a relatively easy thing to do?

title: Can I make existing libraries use external SRAM for the Arduino

Answers: 2

body:
Making a library use external SRAM is not an easy task. It *can* be cone, but it takes quite a bit of work.

The best start would be to abstract the SRAM into a library that provides simple access to it. Then you would need to use that new library to read and write data in the SRAM instead of accessing variables in the other libraries.

There is no way of simply mapping a variable into external SRAM - for that you need a microcontroller with an MMU  and/or an EIB.

body:
> What did programmers do back in the 80-ies when they run out of memory?

There is an old technique called [overlays][1]. The same area of memory is used for different phases/steps of a program. Results are naturally saved but any intermediate data is discharged before the next phase/step which reuses the "common" area of memory. Necessary state may be saved to an external storage between execution of the phase/step to increase available local memory.

To compile and link this you have to do some deep diving into the manual and read up on [memory sections][2].

It is possible to abstract this using C++ smart pointers but getting existing libraries to use it will be a very tough challenge. There are a few attempts to support virtual memory such as [virtmem][3].

Cheers!

  [1]: https://en.wikipedia.org/wiki/Overlay_(programming)
  [2]: http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
  [3]: https://github.com/rhelmus/virtmem


body:
I am trying to use an ESP8266 and an Arduino to access the Arduino from the network. I tried to do something but I'm facing some challenges. I hope I am using the correct board "Generic ESP8266 Module".

[![enter image description here][1]][1]

[![enter image description here][2]][2]

 #include <SoftwareSerial.h>

 const byte rxPin = 2; // Wire this to Tx Pin of ESP8266
 const byte txPin = 3; // Wire this to Rx Pin of ESP8266

 // We'll use a software serial interface to connect to ESP8266
 SoftwareSerial esp8266(rxPin,txPin);

 void setup() {
   Serial.begin(9600);
   esp8266.begin(9600);
   delay(1000);
 }

 void loop() {
   Serial.println("Sending an AT commands");
   esp8266.println("AT");
   delay(30);
   while(esp8266.available()) {
  String data = esp8266.readStringUntil('\n');
  Serial.println("Got response from esp8266: " + data);
   }
 }

**Error**

    Archiving built core (caching) in: C:\Users\XYZ~1\AppData\Local\Temp\arduino_cache_322251\core\core_esp8266_esp8266_generic_CpuFrequency_80,FlashFreq_40,FlashMode_dio,UploadSpeed_115200,FlashSize_512K64,ResetMethod_ck,Debug_Disabled,DebugLevel_None_____feb0d75f3cf4e05271af4f91549cd009.a
    Sketch uses 226657 bytes (52%) of program storage space. Maximum is 434160 bytes.
    Global variables use 32464 bytes (39%) of dynamic memory, leaving 49456 bytes for local variables. Maximum is 81920 bytes.
    warning: espcomm_sync failed
    error: espcomm_open failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed
    error: espcomm_upload_mem failed

[![enter image description here][3]][3]

  [1]: https://i.stack.imgur.com/bxbUr.png
  [2]: https://i.stack.imgur.com/PK7K9.jpg
  [3]: https://i.stack.imgur.com/COggx.png

title: Getting an error while uploading code to Arduino when ESP8266 is attached

Answers: 3

body:
Uploading programs to the Arduino requires the RX and TX lines. The ESP8266 module is probably interfering. You will need to disconnect the ESP8266 module, or at least, don't power the module while uploading.

Connecting the ESP8266 to RX/TX pins will probably also prevent you from using the serial terminal to output debugging information.

An alternative would be to use the (not so great, but it works) [SoftwareSerial](https://www.arduino.cc/en/Reference/SoftwareSerial) library.

body:
First off you have the wrong board selected. It's the Arduino Uno that you are programming, not the ESP8266. Just because you have connected an ESP8266 to the Arduino doesnt't magically change what the Uno is.

Secondly you cannot have anything connected to pins 0 and 1 of the Arduino while programming. Those pins are used for communication with the PC. As a general rule it is best to never use ghem for anything.

To communicate between the Arduino and the ESP8266 you should either pick two other pins and use SoftwareSerial or invest in a board that has at least one independent UART (such as the Mega2560 or the Leonardo).

body:
I believe you are trying to directly program the ESP8266 and you're simply using the Arduino Uno as a USB to serial interface for your computer. There are many tutorials on the web on how to do this. First thing I see wrong with your setup is you've left the Arduino Uno MCU attached to the board. The first thing you'll want to do is remove this chip carefully (the pins can bend easily so apply force evenly). Right now when the Arduino IDE tries to talk to the ESP8266 the communication is going to both the ESP8266 and the Arduino. Physically removing the Arduino MCU chip will ensure any communication is directly with the ESP8266.

Also make sure you are connecting the correct voltage. ESP8266 can only handle 3.3V max, while the Arduino runs at 5V mostly. I believe the Uno board provides a 3.3V output but I'm not 100% sure.


body:
I'm working on a project, where I wish to use pointers. I had a very quick overview of using pointers in C in collage, but I don't know how to use them.

I want that function uses input String (answer) as pointer.

Calling function in setup block

<!-- language: lang-cpp -->

    void setup() {
     sendCommand("AT+RST\r\n", 5000, DEBUG, "ready");
     sendCommand("AT+CWSAP_CUR=\"mega\",\"password123\",10,3\r\n", 4000, DEBUG, "OK");
    }

    String sendCommand(String command, const int timeout, boolean debug, String *answer)
    {
     String response = "";

     Serial1.print(command); // send the read character to the esp8266

     long int time = millis();

     while ((time + timeout) > millis())
     {
      while (Serial1.available())
      {
       // The esp has data so display its output to the serial window
       char c = Serial1.read(); // read the next character.
       response += c;
      }

      //Waiting for the right answer and breaking a while loop
      if (response.indexOf(*answer) > 0)
      {
                break;
      }

     }

     if (debug)
     {
      Serial.print(response);
     }

     return response;
    }

title: How to pass a string pointer to a function

Answers: 3

body:
What you have there are not String objects, but *string literals*. Their type is `const char *`

You should avoid using String objects if at all possible. Instead use character arrays.

To get a character array out of a function it is best to create one outside your function and pass it to the function as one of the parameters. The return value of the function can then be a status value indicating if the call worked or not.

body:
If you want to use the `String` type, have a variable `String rdy="ready";` and pass `&rdy` (the address of the variable). Same with "OK".

I assume you want to use a pointer to avoid copying?

As you are already using C++ techniques (`String` is C++, not C), you might want to consider to pass `rdy` (not a pointer), and to write `const String &answer` in the `sendCommand` parameter list (meaning: reference to a string, which will not be modified), and omit the `*` when using the parameter. Passing references is quite similar to pointers: no copying involved. The additional benefit is that you may even write `sendCommand("AT+RST\r\n", 5000, DEBUG, "ready");` then... the "ready" is automagically converted into a `String`, and passed via reference.

body:
You can pass parameters to functions by reference by value or 'by pointers'.

Passing a parameter by value means that the function has a separate copy of the parameter so this is more expensive in terms of memory.  It also means that any changes you make to the parameter inside the function are not reflected outside the function, they are two separate variables after all.

Passing by reference in C/C++ is done by adding a & after the parameter's type, `(int& byRef)`.  This means that you are using the same variable inside and outside of the function.  If you want to prevent the function changing the value then you set the parameter to be a constant reference. `const int& constByRef`

There is a third method which is passing a pointer.  This is very useful for parameters that are a few bytes in size, i.e. strings and structures `char* ptr`.  When you pass a pointer it is passed by value, you can modify the pointer or the data it points to.  Since a pointer is usually only the word size of the processor it is only as expensive as passing an int parameter.

When you pass a `const char* cPtr` you can not modify the value of the pointer, but you can modify the value of the data pointed to.  This type of parameter will let you pass in string literals.

To make you code cleared always write functions to accept constant parameters.  If the parameter is larger than a word pass it by reference unless its an array (including char*) in which case pass it by pointer.  If in doubt it should be a constant reference to start with.  Sometimes embedded constraints affect these rules.


body:
I'm using a Lidar Lite v3 to measure the distance from one object to another. I pass the results to the serial monitor to see what that distance is. It appears that when I call an unrelated function, the distance that's being printed seems to be roughly subtracted by 512.

To describe exactly what I mean, this is my function:

    int pulseWidth = pulseIn(monitorPin, HIGH); //begin measurement of time
    int distanceConverted = (pulseWidth / 10); // 10usec = 1 cm of distance
    Serial.println(distanceConverted); // Print the distance

and it gives me an output of this (which is correct):

    780 cm
    787 cm
    790 cm
    794 cm
    782 cm
    787 cm
    790 cm
    786 cm
    790 cm
    780 cm
    788 cm
    784 cm

I'm using these distances to control LED lights and a speaker, and call this function to do so:

    void lights(int distanceConverted)
    {
        if (distanceConverted < 1000 && distanceConverted > 500)
        {
          digitalWrite(yellowLEDPin, HIGH);
          delay(20);
          tone(8, 35000, 250);
        }

        else if (distanceConverted <= 500)
        {
          digitalWrite(redLEDPin, HIGH);
          delay(20);
          tone(8, 40000, 250);
        }
    }

However, when this is called (and I call the function after I print the distance values), these are the results I get:

    268 cm
    267 cm
    266 cm
    267 cm
    269 cm
    267 cm
    265 cm
    267 cm
    266 cm
    266 cm
    267 cm
    264 cm
    269 cm

When I try to account for this and multiply by three, my values become even more off and seem to be multiplied by ten:

    int distanceConverted = (pulseWidth / 10)*3; // 10usec = 1 cm of distance

    New Values:
    2640 cm
    2673 cm
    2634 cm
    2649 cm
    2592 cm
    2619 cm
    2631 cm
    2628 cm
    2631 cm
    2673 cm
    2634 cm

At first I thought it might have been the delays within the lights() function manipulating the readings, but even after commenting them out I still get the same results. I don't know how the function could be throwing my values off.

Edit: I noticed at when the program is first looping, the 512 gets subtracted after the first time I run through the lights() function.

    761 cm <- first value from sensor, correct
    312 cm
    308 cm
    308 cm
    309 cm
    308 cm
    307 cm
    307 cm
    309 cm
    308 cm
    308 cm

When I comment out the tone() function, that seems to fix my problem. Could that function be overwriting a bit in the memory register causing it to subtract 512 from my distanceConverted variable?

title: Distance Readings Getting Manipulated When Calling Unrelated Function

Answers: 1

body:
The tone function uses timer interrupts to toggle a GPIO pin to make noise. That's quite intense from a CPU point of view and is most likely skewing the timing of the pulseIn function.

I would suggest not using tone if you can help it. Maybe change the frequency of a PWM output to something suitable and use analowWrite to create a 50% duty square wave.

Also learning how to use the Input Capture peripheral of the MCU (read the datasheet) will enable you to perform asynchronous sampling of your pulses and obtain much more accurate results.


body:
I have problem with baud rate. I have changed baud rate of esp from 115200 to 9600 with AT command AT+CIOBAUD. And everything worked fine until I wanted to change it back and executed command AT+CIOBAUD115200, after which everything I send trough arduino IDE serial monitor to ESP I get gibberish. I have tried all baud rated available in serial monitor but got nothing. Wiring stayed the same.

    TX -> arduino RX
    RX -> arduino TX
    GND -> GND
    CH_PD -> 3,3V
    VCC -> 3,3V

I thought that if I can flash ESP firmware it will get back all default parameters, hence I tried flow these steps ([link][1]) but I stopped when executed `esptool.py --port /dev/ttyACM0 erase_flash` which got me

    esptool.py v1.3
    Connecting...................

    A fatal error occurred: Failed to connect to ESP8266: Invalid head of packet ('\x00')

In some forums is said that to get rid of error I need to change baud rate, but nothings works for me.

Please advise how can I fix this problem.

  [1]: http://cordobo.com/2300-flash-esp8266-01-with-arduino-uno/

title: Can't send AT comands to ESP8266 on any baud rate

Answers: 0


body:
Ok, I am trying to make 2 LEDs run at two different speeds.

Here is the code I am using:

    void setup() {

      pinMode(13, OUTPUT);
      pinMode(12, OUTPUT);
    }

    for ( ; ; ) {
      for ( ; ; ) {
       digitalWrite(12, HIGH);
       delay(250);
       digitalWrite(12, LOW);
       delay(250);
      }
      digitalWrite(13, HIGH);
      delay(500);
      digitalWrite(13, LOW);
      delay(500);
    }

This code unfortunately returns this error:

    error: expected unqualified-id before 'for'
     for ( ; ; ) {

Thanks for the help!

title: Nested for loop errors

Answers: 3

body:
As Majenko's comments are suggesting you're missing the `loop` function here - which is not just eye candy but essential. It is the basic structure of the [sketches](https://www.arduino.cc/en/Tutorial/BareMinimum) to have two methods on the highest (user accessible) level: `void setup()` and `void loop()`. `setup` is run exactly once at the beginning of your program. Following that `loop` is looped (hence the name) forever.

This is what it should look like:

    void setup() {
      // doing the setup
    }

    void loop() {
        for ( ; ; ) {
            for ( ; ; ) {
                // something
            }
            // something else
        }
    }

However (and again Majenko's comment hints it) `something else` is never going to be executed as the inner loop is never exited. This [tutorial](https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay) (per Majenko's comment) should get you started. See also: [www.arduino.cc](https://www.arduino.cc/en/Tutorial/BuiltInExamples) with many more tutorials worth studying.

body:
First of all your question is so basic it means you didn't spend any time to look any example out there, not even after Majenko has clearly pointed out you can find the answer to your question in the many examples out there.

Once that is clear here follow the code you are looking for, but using it as it is without knowing what you are doing is not going to help you. Not to mention not many will be willing to help somebody with the attitude you are demonstrating.

    #define LED_1 5
    #define LED_2 6

    void setup() {
      pinMode(LED_1, OUTPUT);
      pinMode(LED_2, OUTPUT);
    }

    long one, two;
    bool led_1, led_2;

    void loop() {
      if (millis() - one >= 250) {
        digitalWrite(LED_1, led_1++);
        one = millis();
      }

      if (millis() - two >= 500) {
        digitalWrite(LED_2, led_2++);
        two = millis();
      }
    }

body:
You have a compiler error because you have executable code outside a function. In particular your first "for" loop.

Second, an infinite loop inside an infinite loop is not particularly useful.

> so how do I make it run both at the same time?

Ah yes, well unless you have multiple CPUs you don't run multiple things "at the same time". You do one thing, and then another thing.

I have an article about this general idea here:

http://www.gammon.com.au/blink

To save having to necessarily go to that link, here is an example from that page which blinks two LEDs at different rates:

    // Which pins are connected to which LED
    const byte greenLED = 12;
    const byte redLED = 13;

    // Time periods of blinks in milliseconds (1000 to a second).
    const unsigned long greenLEDinterval = 500;
    const unsigned long redLEDinterval = 1000;

    // Variable holding the timer value so far. One for each "Timer"
    unsigned long greenLEDtimer;
    unsigned long redLEDtimer;

    void setup ()
      {
      pinMode (greenLED, OUTPUT);
      pinMode (redLED, OUTPUT);
      greenLEDtimer = millis ();
      redLEDtimer = millis ();
      }  // end of setup

    void toggleGreenLED ()
      {
       if (digitalRead (greenLED) == LOW)
          digitalWrite (greenLED, HIGH);
       else
          digitalWrite (greenLED, LOW);

      // remember when we toggled it
      greenLEDtimer = millis ();
      }  // end of toggleGreenLED

    void toggleRedLED ()
      {
       if (digitalRead (redLED) == LOW)
          digitalWrite (redLED, HIGH);
       else
          digitalWrite (redLED, LOW);

      // remember when we toggled it
      redLEDtimer = millis ();
      }  // end of toggleRedLED

    void loop ()
      {

      // Handling the blink of one LED.
      if ( (millis () - greenLEDtimer) >= greenLEDinterval)
         toggleGreenLED ();

      // The other LED is controlled the same way. Repeat for more LEDs
      if ( (millis () - redLEDtimer) >= redLEDinterval)
        toggleRedLED ();

    /* Other code that needs to execute goes here.
       It will be called many thousand times per second because the above code
       does not wait for the LED blink interval to finish. */

    }  // end of loop

In that code, in the main loop, the code uses `millis()` to find the current time, and if sufficient time has elapsed it does something useful. As an analogy, when you are cooking dinner you look at the clock from time to time, and if sufficient time has elapsed since you started cooking, you take the roast from the oven and eat it.


body:
I have a motor shield V2 on my Arduino, i compile the codes just fine and i'm trying to just run the example dc motor test. The code compiles the serial is printing out the "tick tock ...." but the motors are not running. They ran once before on my mac though.

Using a 9v battery to power a basic Dc motor.

I'm using the right ports on pc. Same exact port for motor as the code tells. I'm not sure where i am wrong. TYIA

[![enter image description here][1]][1]
[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/KCAAL.jpg
  [2]: https://i.stack.imgur.com/rQ08I.jpg

title: Arduino MotorShield code running but not motors

Answers: 2

body: Turns out the pins connecting the shield to the Arduino are quite loose and didn't "touch" the Arduino.

body:
>Using a 9v battery to power a basic Dc motor.

Don't do that.  These were designed for early transistorized radios, which needed a moderately high voltage but very low current.

There are very few motors with suitable low-current coil characteristics to be driven by such a battery.  Others might work at best briefly before killing the battery.

If you need around 9 volts for a motor project, you should probably use 6 or so AA cells.


body:
I am doing a fingerprint sensor that works with a 16x2 LCD. The code works correctly for the fingerprint sensor, but when I enter LCD code, the LCD works but the fingerprint stops working.

I am using an Arduino Uno and an Adafruit fingerprint sensor. Both the fingerprint and LCD are wired correctly and work separately. I have enrolled and tested fingerprints and it worked perfectly until I added LCD code.

    #include <Adafruit_Fingerprint.h>
    #include <SoftwareSerial.h>
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

    int getFingerprintIDez();
    // pin #2 is IN from sensor (GREEN wire)
    // pin #3 is OUT from arduino  (WHITE wire)
    SoftwareSerial mySerial(2, 3);

    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

    void setup() {
     // set up the LCD's number of columns and rows:
      lcd.begin(16, 2);
      // Print a message to the LCD.
      lcd.print("hello, world!");
      Serial.begin(9600);
      Serial.println("fingertest");
      // set the data rate for the sensor serial port
      finger.begin(57600);
      if (finger.verifyPassword()) {
        Serial.println("Found fingerprint sensor!");
      } else {
        Serial.println("Did not find fingerprint sensor :(");
        while (1);
      }
      Serial.println("Waiting for valid finger...");
    }

    void loop() {
      getFingerprintIDez();
    }

    uint8_t getFingerprintID() {
      uint8_t p = finger.getImage();
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image taken");
          break;
        case FINGERPRINT_NOFINGER:
          Serial.println("No finger detected");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_IMAGEFAIL:
          Serial.println("Imaging error");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      // OK success!
      p = finger.image2Tz();
      switch (p) {
        case FINGERPRINT_OK:
          Serial.println("Image converted");
          break;
        case FINGERPRINT_IMAGEMESS:
          Serial.println("Image too messy");
          return p;
        case FINGERPRINT_PACKETRECIEVEERR:
          Serial.println("Communication error");
          return p;
        case FINGERPRINT_FEATUREFAIL:
          Serial.println("Could not find fingerprint features");
          return p;
        case FINGERPRINT_INVALIDIMAGE:
          Serial.println("Could not find fingerprint features");
          return p;
        default:
          Serial.println("Unknown error");
          return p;
      }

      // OK converted!
      p = finger.fingerFastSearch();
      if (p == FINGERPRINT_OK) {
        Serial.println("Found a print match!");
      } else if (p == FINGERPRINT_PACKETRECIEVEERR) {
        Serial.println("Communication error");
        return p;
      } else if (p == FINGERPRINT_NOTFOUND) {
        Serial.println("Did not find a match");
        return p;
      } else {
       Serial.println("Unknown error");
        return p;
      }

      // found a match!
      Serial.print("Found ID #");
      Serial.print(finger.fingerID);
      Serial.print(" with confidence of ");
      Serial.println(finger.confidence);
    }

    // returns -1 if failed, otherwise returns ID #
    int getFingerprintIDez() {
      uint8_t p = finger.getImage();
      if (p != FINGERPRINT_OK)  return -1;
      p = finger.image2Tz();
      if (p != FINGERPRINT_OK)  return -1;
      p = finger.fingerFastSearch();
      if (p != FINGERPRINT_OK)  return -1;
      // found a match!
      Serial.print("Found ID #");
      Serial.println(finger.fingerID);
      Serial.print("This Finger print related to : ");
      switch(finger.fingerID){
       case 0:
         Serial.println("Subhy Mesmar");
         break;
       case 1 :
         Serial.println("Amjad Mesmar");
         break;
      }
      return finger.fingerID;
    }

In this image the fingerprint sensor works without LCD code:

[![Fingerprint sensor works without lcd code][1]][1]

And in this one the LCD works after adding code but the fingerprint sensor stopped working:

[![lcd works after adding code but fingerprint sensors stopped working][2]][2]

  [1]: https://i.stack.imgur.com/bNRo5.jpg
  [2]: https://i.stack.imgur.com/GcKIu.jpg

title: Fingerprint sensor code won't work correctly with LCD 16x2

Answers: 1

body:
You have pins 2 and 3 used by both the LCD and the SoftwareSerial used for the fingerprint sensor.

Use different pins for one or the other.

Worth looking at [the Software Serial reference][1] to understand more about how it works.

  [1]: https://www.arduino.cc/en/Reference/SoftwareSerial


body:
I was able to send a text file in the SD card to NodeMCU using the serial port of an Arduino Mega using this code:
<!-- language-all: lang-cpp -->

    if (readSerial1 == "Okay I'm ready") {
      myFile = sdf.open("uid.txt", FILE_READ);
      if (myFile) {
        while (myFile.available()) {
          char toUID = myFile.read(); //read each char and store to toUID
          uidContent += toUID; //store char to form a String
        }
        Serial1.print(uidContent);
        myFile.close();
      }
    }

And it will be read by the NodeMCU then sent to another NodeMCU and stored in the SD of another Mega wirelessly using this code.

    while (1) {
      if (Serial.available()) {
        uid = Serial.readString();
        break;
      }
    }
    data = uid.c_str();
    port.beginPacket("192.168.4.255", 2390);
    port.write(data);
    port.endPacket();

Now, is it possible to send a wav/mp3 file using this process or is there any other way?

title: Send .wav file from SD card to NodeMCU via serial port

Answers: 0


body: I know this that when you try to program a pro mini without a DTR pin it will give you a error as the atmega needs to be reset during programming. So I had a doubt why does the microcontroller needs to be reset and clearly at which time you know at which moment does it reset ?

title: Auto Reset during programming Arduino

Answers: 1

body: A Reset is necessary to activate the Bootloader and allow programming. Without the DTR signal the Reset button has to be pressed just before starting the upload from the Arduino IDE.


body:
can I power up my Arduino UNO with four AA batteries? It's about 6V, will my arduino burn? And, if I power my Arduino, I have to power my Motor Shield too or not?

I want to make line follower. I have to know what I have to power up. I dont know, how many battery holders I need. I have: Arduino UNO, motor shield, two 6V DC motors

title: Can I power up my Arduino and MotorShield with four AA batteries?

Answers: 3

body:
You won't damage the Arduino if you remove the power to the motors as even though you're using the same power supply to power the motots and Arduino (4 x 1.5 - 6V batteries) you're not powering it from the Arduino pins itself.

What exactly are you trying to accomplish here?  Post some more info.

body:
> can I power up my Arduino UNO with four AA batteries?

6v is about the max if it is directly applied to the chip;

6v is just shy of the minimum if it is applied to a regulator and then to the chip.

body:
It won't cause damage to connect 4xAA to the input of the Arduino's regulator, however it also won't result in specified operation, as even with fairly new cells the voltage will below that which the typically used 5v regulators require to deliver 5v at the output.

Additionally, the common L293D and L298 based bipolar motor shields are horribly lossy.  Feed them about 6v input, and you'll get just over 4v to your motor, which is likely to be disappointing.

To build an Arduino-based battery-powered motor project, you typically need to do one of two things

- Use 6, 7, 8 or more cells, and higher-voltage, lower current motors

- Use a 3.3v Arduino and a more efficient FET-based H-bridge motor driver/shield, for example the TB6612FNG.   This supports 4 cell operation quite well, and may to a more limited degree work on 3 *alkaline* cells.


body:
I am tying to design my circuit diagram with the help of http://fritzing.org/home/ I designed like below circuit where wires are simply straight.

[![enter image description here][1]][1]

I want some kinda jumping wires with this tool. Does anyone know how to create these jumping wires ?

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/Nk1RT.png
  [2]: https://i.stack.imgur.com/KYbW1.png

title: How to create jumping wire using fritzing tool

Answers: 1

body:
1. Draw the wires
2. press and hold control button (mouse pointer will appear with a curve symbol)
3. drag the wire using mouse

[![enter image description here][1]][1]

[![enter image description here][2]][2]

  [1]: https://i.stack.imgur.com/veD8K.png
  [2]: https://i.stack.imgur.com/AtNhI.png


body: Recently I was checking out the Atmel's AVR series and I found the Atmega328PB. I am really familiar with Arduino's environment. So I thought if somehow we could bootloader it with Arduino bootloader. My doubt is how can I make a Arduino bootloader for it.

title: Building Custom Bootloaders

Answers: 1

body:
Here are a couple sources of ATmega328PB bootloaders based on optiboot:

- https://github.com/watterott/ATmega328PB-Testing
- https://github.com/ElektorLabs/Arduino

I haven't used either.
If you are set on making your own at least they can provide you with a reference.


body: I am trying to make my own mouse/keyboard from an attiny (it doesn't have to be attiny102 as the title suggests). I have read many articles on this subject: some are using v-usb library.But I understand this is for arduino uno/leonardo.I want to use an attiny with the least amount of electronic parts attached to it(no external oscillator-only the internal one..etc.). All the articles I read said that arduino can't be used as a host usb device but this applies only for it's built-in micro-usb. Can't I just emulate the HID device using digital pins on my attiny? If this is possible where can you provide some well-documented source for the protocol used when communicating with the pc?

title: Using ATiny102 as HID device(emulating mouse)

Answers: 2

body:
I have build a HID midi keyboard with the hiduino lib which is base on LUFA.
http://code.google.com/p/hiduino/w/list

I know LUFA is also capable to build a HID mouse device. But you need to switch to a bigger controller (i think). I used a 8u2 from atmel.

I used AVR Studio 6 to compile hiduino.
Currently i have no link to the LUFA because the git page is gone. Maybe you find a mirror or a other webpage.

body:
the only USB option for AVR microcontrollers without embedded USB, is VUSB which is somehow rare in Arduino; despite some aged libraries around :

https://blog.petrockblock.com/2012/05/19/usb-keyboard-with-arduino-and-v-usb-library-an-example/
https://github.com/gloob/vusb-for-arduino

but if you can rely on atmel studio, the very rich examples of VUSB itself are enough. I made a HID presenter (just two keys to go back and forth on powerpoint slides) using only an attiny24 which is super cheap. the codeandlife blog is a good start for VUSB. it also has a HID mouse example explained :

http://codeandlife.com/2012/02/11/v-usb-tutorial-continued-hid-mouse/


body:
I am trying to send a value from Arduino to a remote MySQL. I am following [this tutorial][1].

I have tried but no data is received on the server. What is the issue? I am new to Arduino. My code is:

    int led1=8;
    int count=1;
    void setup() {
      pinMode(led1, OUTPUT);
      delay(3000);
      // initialize serial communication at 9600 bits per second:
      Serial.begin(115200);
      Serial.println("AT+CWMODE=1");
      delay(1000);
      Serial.println("AT+CWJAP=\"mhboys\",\"mhboys123\"");
      delay(1000);
    }

    // the loop routine runs over and over again forever:
    void loop() {
      digitalWrite(led1,HIGH);
      // turn the LED on (HIGH is the voltage level)
      delay(1000);  // wait for a second
      if(digitalRead(led1)==LOW) {}
      if(digitalRead(led1)==HIGH) {
        count++;
        //code for sending updated count to mysql
      }
      digitalWrite(led1, LOW);
      // turn the LED off by making the voltage LOW
      delay(1000); // wait for a second
      int adjustedValue = count;
      // print out the value you read:
      Serial.println("AT+CIPSTART=\"TCP\",\"www.onemediagroup.in\",80");
      delay(1000);
      Serial.println("AT+CIPSEND=66");
      delay(1000);
      Serial.print("GET /energy/getUsage.php?currentValue=");
      Serial.print(adjustedValue);
      delay(1000);
      Serial.println("AT+CIPCLOSE");
      digitalWrite(13, HIGH);
      delay(100000); // delay in between reads for stability
    }

  [1]: http://bryceautomation.com/index.php/2016/12/24/logging-data-to-web-page-using-arduino-and-esp8266-01-at-command-set/

title: Sending value from Arduino to MySQL using ESP8266

Answers: 1

body:
You're sending commands blindly without checking if they actually succeeded. If you're not ready to correctly handle the responses, you're better off using a library like [this][1]. The 'HTTP GET' example should help.

  [1]: https://github.com/itead/ITEADLIB_Arduino_WeeESP8266


body:
I am using both an RFID and a fingerprint sensor in my project. When running the program, the RFID is detected but the fingerprint sensor is not detected and hence my code is not going forward.

Here is my code

    #include <Adafruit_Fingerprint.h>
    #include <SoftwareSerial.h>
    #include <MFRC522.h>
    #include <SPI.h>

    #define SAD 10
    #define RST 5
    MFRC522 nfc(SAD, RST);

    uint8_t id;
    uint8_t getFingerprintEnroll();
    int getFingerprintIDez();

    // pin #2 is IN from sensor (GREEN wire)
    // pin #3 is OUT from arduino  (WHITE wire)
    SoftwareSerial mySerial(2, 3);
    Adafruit_Fingerprint finger = Adafruit_Fingerprint(&mySerial);

    void setup() {
       SPI.begin();
       Serial.begin(115200);
        Serial.println("Looking for MFRC522.");
       nfc.begin();
       byte version = nfc.getFirmwareVersion();
      if (! version) {
        Serial.print("Didn't find MFRC522 board.");
        while (1); //halt
      }

      Serial.print("Found chip MFRC522 ");
      Serial.print("Firmware ver. 0x");
      Serial.print(version, HEX);
      Serial.println(".");
      Serial.begin(9600);

      Serial.println("Fingerprint and RFID Test");

      finger.begin(57600);
      if (finger.verifyPassword()) {
       Serial.println("Found fingerprint sensor!");
      } else {
        Serial.println("Did not find fingerprint sensor :(");
        while (1);
      }
    }

    char abc;
    void loop() {
        abc = Serial.read();
        switch (abc) {
          case '1': {
                 //Enroll method
          }
          break ;
          case '2': {
            //verify method
          }break;
          case '3': {
           //rfid method
          }
       }
    }

title: Using RFID and fingerprint sensor together

Answers: 1

body: Get rid of the `Serial.begin(9600)`. You're accidentally changing the `Serial` baud rate without doing the same in the serial monitor so you'll probably see gibberish, if anything.


body:
I am using ESP8266 01 board to send some data via TCP to server on local network. My code is:

    #include <ESP8266WiFi.h>

    const char* ssid     = "ssid";
    const char* password = "pas";

    const char* host = "192.168.1.103";

    void setup() {
      Serial.begin(115200);
      delay(10);

      // Wifi connection

      Serial.println();
      Serial.println();
      Serial.print("Connecting to ");
      Serial.println(ssid);

      WiFi.begin(ssid, password);

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

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

       delay(5000);

      Serial.print("connecting to ");
      Serial.println(host);

      // Use WiFiClient class to create TCP connections
      WiFiClient client;
      const int port = 8888;
      if (!client.connect(host, port))
      {
        Serial.println("connection failed");
        return;
      }

    }

    void loop() {

      while(Serial.available() == 0)
      {
        //wait for arduino serial data
      }

       while(Serial.available())
      {
        // send data to server
        client.print(Serial.read());
      }
    }

After chacking code in Arduino IDE I am getting error message:

    In function 'void loop()':
    espwifitcp1:57: error: 'client' was not declared in this scope
         client.print(Serial.read());
         ^
    exit status 1
    'client' was not declared in this scope

It appears that if I declare `WiFiClient client;` inside `setup()` function it can't be accessed outside it. Do I correctly understand the problem? I have tried to declare object outside `setup()` and `loop()` functions but it got even more errors. Any suggestions?

title: ESP8266 TCP connection WiFiClient issue

Answers: 2

body: You have declared `WiFiClient client;` in the scope of setup() only. Move it's declaration to the global scope by placing it above the declaration of `void setup()`

body: in the header include WifiClient.h


body:
I am trying to make a state machine with if/else. But some of the code does not seem to be executing. I have information being displayed on an LCD screen so I know where it is, and it stays on **Todo=1** and does not go to the next state. I have tried using switch/case and it works. But I think it might be better for my project if I use if/else. Can I do this using if/else?

    Void loop{
      if (state == PLAY) {
        Todo = 1;
        Mastermachine(Todo);
      } else if (state == TRYAGIN) {

      }
    }

    void Mastermachine(int Todo) {
      if (Todo == 1) {
        lcd.setCursor(16, 2);
        lcd.print(String(Todo));
        SongSeq[largestindex];
        for (int index = 0; index < largestindex; index++) {
          SongSeq[index]();
        }
        Todo = 2;
      } else if (Todo == 2) {
        for (learnindex = 0; learnindex < largestindex;) {
          MIDI.read();
          if (learnindex >= largestindex) {
            Todo = 3;
          }
          lcd.setCursor(16, 2);
          lcd.print(String(Todo));
        }
      } else  if (Todo == 3) {
        if (array_cmp(learn, note, largestindex, largestindex) == true) {
          largestindex++;
          delay(2000);
          Todo = 1;
        } else {
          delay(2000);
          Todo = 1;
        }
        lcd.setCursor(16, 2);
        lcd.print(String(Todo));
      }
    }

title: State Machine with If/Else?

Answers: 2

body:
Your loop executes continually, always setting the state to 1.....

The called state machine supposedly changes the state, but it get set back to 1 every time the loop executes.

The loop program needs to do the state changes, not the masternachine function.

body:
Inside Mastermachine(), Todo is *a copy* whatever is passed as its paramter. Even if you make a global named Todo, it will be 'hidden' by the parameter of the same name. That parameter goes out of scope - disappears - when Mastermachine() exits, including any changes made to it within the function.

There are a few choices to accomplish what you want to do, but the easiest is probably to make a global Todo and get rid of the parameter Todo in Mastermachine(); i.e., make it `void Mastermachine(void)`. Then the name Todo inside the function will refer to the global by that name.


body:
I need help with my project. In my project, I have two homemade capacitors made from 2 aluminum foil strips separated by a water bottle. I need to detect which bottle is going to become empty as people drink from it. So I plan to use the change in capacitance to detect the empty bottle. I know how to measure capacitance of 1 bottle and detect the change, but I don't know how to do it to 2 bottles at a time. Any ideas how to do this?
Here is the following code, I have been working on.

    // Initialize Pins
    int analogPin = 0;
    int analogPin1=1;
    int chargePin = 13;
    int chargePin1=12;
    int dischargePin = 11;
    int dischargePin1 = 10;

    // Initialize Resistor
    int resistorValue = 10000;

    // Initialize Timer
    unsigned long startTime;
    unsigned long elapsedTime;

    // Initialize Capacitance Variables
    float microFarads;
    float microFaradr;
    float nanoFarads;
    float nanoFaradr;

    void setup()
    {
      pinMode(chargePin, OUTPUT);
      pinMode(chargePin1,OUTPUT);
      digitalWrite(chargePin1,LOW);
      digitalWrite(chargePin, LOW);
      Serial.begin(9600); // Necessary to print data to serial monitor over USB
    }

    void loop()
    {
      digitalWrite(chargePin, HIGH); // Begins charging the capacitor
      digitalWrite(chargePin1,HIGH);
      startTime = millis(); // Begins the timer

      If(analogRead(analogPin)>648){
        elapsedTime= millis() - startTime;
        microFarads = ((float)elapsedTime / resistorValue) * 1000;

        if (microFarads == X) // X is an arbitrary capacitance when the bottle is empty and X is not a variable
        {
          Serial.println(" Bottle A is empty");
        }

        digitalWrite(chargePin, LOW); // Stops charging capacitor
        pinMode(dischargePin, OUTPUT);
        digitalWrite(dischargePin, LOW); // Allows capacitor to discharge
        while(analogRead(analogPin) > 0)
        {
          // Do nothing until capacitor is discharged
        }
        pinMode(dischargePin, INPUT); // Prevents capacitor from discharging
      }

      If(analogRead(analogPin1)>648){
        elapsedTime= millis() - startTime;
        microFaradr = ((float)elapsedTime / resistorValue) * 1000;

        if (microFaradr == Y) // Y is an arbitrary capacitance when the bottle is empty and Y is not a variable
        {
          Serial.println(" Bottle B is empty");
        }

        digitalWrite(chargePin1, LOW); // Stops charging capacitor
        pinMode(dischargePin1, OUTPUT);
        digitalWrite(dischargePin1, LOW); // Allows capacitor to discharge
        while(analogRead(analogPin1) > 0)
        {
          // Do nothing until capacitor is discharged
        }
        pinMode(dischargePin1, INPUT); // Prevents capacitor from discharging
      }
    }

title: Measuring the capacitance of 2 capacitors at a time

Answers: 1

body:
Before we get started, there are a few problems with your code.

First, I wouldn't check for `==648` or `==0`: what if you miss it by a moment and it jumps to 649, or it doesn't quite discharge to 0v?  I'd use `>=648` and `<=2` (or some other similarly low number - experimentation required).

How is your circuit connected?  I can't quite get my head around the charge and discharge pins, but I'll stick with what you have, assuming it works.

You say you want measurements every 30s, but don't say how long they take. (I have no idea of the capacitance of your bottle.)  My code assumes it takes much less than 30s to measure one bottle.  If it takes near to 30s to do one, this won't work.

I'll also assume your code works.  This is a bad assumption, since it won't even compile (capital `I` in `if`) but regardless, that's what I'll assume.

All that being said, here's the code:

    // Pins connections
    int analogPinA = 0;
    int analogPinB = 1;
    int chargePinA = 13;
    int chargePinB = 12;
    int dischargePinA = 11;
    int dischargePinB = 10;

    // Resistor being used
    int resistorValue = 10000;

    void setup()
    {
      pinMode(chargePinA, OUTPUT);
      pinMode(chargePinB, OUTPUT);
      digitalWrite(chargePinA, LOW);
      digitalWrite(chargePinB, LOW);
      pinMode(dischargePinA, OUTPUT);
      pinMode(dischargePinB, OUTPUT);
      digitalWrite(dischargePinA, LOW);
      digitalWrite(dischargePinB, LOW);
      Serial.begin(9600);
    }

    // Measure the capacitance of specified capacitor
    float measureCapacitance(int analogPin, int chargePin, int dischargePin)
    {
        // Ensure the capacitor is discharged
        digitalWrite(dischargePin, LOW);
        while (analogRead(analogPin)>2) { /* Do nothing */ }
        pinMode(dischargePin, INPUT);

        // Start charging
        unsigned long startTime = millis();
        digitalWrite(chargePin, HIGH);

        // Wait for the capacitor to charge
        while (analogRead(analogPin)<=648) { /* Do nothing */ }
        unsigned long endTime = millis();

        // Start it discharging again, ready for next time
        pinMode(dischargePin, OUTPUT);
        digitalWrite(dischargePin, LOW);

        // Calculate measured capacitance
        unsigned long elapsedTime = endTime - startTime;
        float microFarads = ((float)elapsedTime / resistorValue) * 1000;
        return microFarads;
    }

    void loop()
    {
        // Measure capacitance of first bottle
        float microFarads = measureCapacitance(analogPinA, chargePinA, dischargePinA);
        if (microFarads <= X) // X is an arbitrary capacitance when the bottle is empty
        {
          Serial.println("Bottle A is empty");
        }

        // Measure capacitance of second bottle
        float microFarads = measureCapacitance(analogPinB, chargePinB, dischargePinB);
        if (microFarads <= X) // X is an arbitrary capacitance when the bottle is empty
        {
          Serial.println("Bottle B is empty");
        }
    }


body:
I'm developing a low power data logging device. It samples sensors at the frequency of 20Hz, and also has a real time clock for absolute time (the logged time need to be exact down to ms).

I think that querying time for every samples would be wasteful of energy. One solution is calculate time based on number of cycles, and after a fixed duration (10 minutes) query RTC to update the time.

Here is my attempt:

    #define INTERVAL 12000 //10 minutes: 10*60*20 samples

    int count = 0;
    int checkPointMillis;
    int checkPointRTC;

    // timer interrupt at 20Hz
    ISR() {
     int a = analogRead(A0);
     int time = millis() - checkPointMillis + checkPointRTC;

     // write data to a buffer

     if (count > INTERVAL) {
      count = 0;
      checkPointMillis = millis();
      checkPointRTC = getRTCTime();
     }
    }

Is this a correct approach?

title: Calculate absolute time based on cycles and RTC

Answers: 3

body:
In general, the idea is sound.  But there are problems with some of the details and tuning.

The most important detail:  Use the correct data type for storing and computing with time variables (like `time`, `checkPointMillis` and `checkPointRTC`).  The correct data type is `unsigned long` (or, equivalently, `unsigned long int` or `uint32_t`).

A second detail:  Rather than storing your calibration correction in two variables which you always use as a difference (in effect, `checkPointRTC-checkPointMillis`) just compute and store the difference.  For example:

    ...
    unsigned long clockCorrection;
    ...
    unsigned long time = millis() - clockCorrection;
    ...
    clockCorrection = getRTCTime() - checkPointMillis;

This will save a few bytes of RAM and a few cycles of computation.

A third detail:  If outside of the ISR you will need to access any of the values computed in the ISR, declared their variables `volatile`.  Example:

    volatile unsigned long time;

Fourth: If `getRTCTime()` or any of your sensor-reading code use interrupts, you will need to move such code out of the “timer interrupt at 20Hz” section, into (for example) `loop()`, triggered by a volatile variable going true.  [That's the model under which the balance of this answer was conceived; I overlooked, at first, the “timer interrupt at 20Hz” label.]  Note that `millis()` itself does not use interrupts.  But if your 20-Hz ISR runs longer than a millisecond, the `millis()` total will drop one millisecond per millisecond of additional ISR time.

By tuning, I refer to the number of measurement intervals to wait between recomputing the clock correction.  Under reasonable assumptions, the number of compute cycles is so closely the same with a one second interval versus a ten minute interval, that one probably should use only a second (or at the outside, a minute) interval between clock correction computes.

For example, suppose the total number of cycles awake per second is given by the following equation:

>a = 20*s + 1000*t + k * r

where *s* is the number of cycles used per sensor-set reading and recording; *t*  is the number of cycles used per clock interrupt; *k* is the number of clock correction computes per second; and *r* is the number of cycles used per clock correction compute.

For example, if *s* is 2000, *t* is 100, and *r* is 200, the equation becomes

>a = 20*2000 + 1000*100 + k * 200 = 140000 + k * 200

Now consider three cases: *k* equal to 20, or 1, or 1/600, corresponding to a clock correction compute 20 times per second, or once a second, or every 10 minutes:

       k           a
      20        144000
       1        144200
    1/600       144000.3

As you can see, under the assumptions *s* is 2000, *t* is 100, and *r* is 200, there is no compelling reason to prefer 1/600 corrections per second to one  correction per second.

If your RTC can be read reliably and quickly, reading it either every time (ie 20 per second) or every second has other advantages:  you compensate more quickly for MCU clock drift (ie, every second, rather than every 10 minutes) and strongly decrease the risk of out-of-order times.

For example, if your MCU clock drifts 2 seconds fast per 10 minutes, readings taken during the first two seconds of each new 10-minute interval would show smaller times than those taken during the last two seconds of the previous interval.  With secondly corrections, no such non-monotonic readings will occur.

Here is a slightly more correct analysis of the 2 seconds fast per 10 minutes case:  2 seconds error in 600 seconds is 3.33 milliseconds per second.  With sensor readings 50 milliseconds apart, and corrected clock readings not more than 3.33 milliseconds out of whack, non-monotonicity won't occur.  However, this does not meet the “logged time needs to be exact down to ms” criterion.  To meet that, drift of more than a half millisecond must be prevented.  That requires drift correction at least 6.67 times per second.  You could accomplish that by making a  clock correction compute at every third sensor cycle.

It should be clear from the example calculations of awake cycles that the major contributor to the count is ISR cycles, here taken as 100*1000, or 100000 cycles per second.  You could set up timer 1 to interrupt 20 times per second and turn timer 0 off (which would disable `millis()` and require a different `time = ...` formula).  If each timer 1 interrupt took 1000 cycles, that would contribute 20000 cycles instead of 100000 per second.

*Edit 4:* As I noted in a comment to Edgar Bonet's answer, one can change the TOP value used for timer interrupts, to control interrupt rate with better resolution than can be obtained by merely subtracting base values.

According to Gerben's comment, “`getRTCTime` only has 1sec resolution”.  As I haven't seen any code for your `getRTCTime()` I don't know if that is true or not; but if so, here is another approach for time-rate correction:

>• At some beginning point coincident with an RTC seconds-change, record `millis()` and an RTC reading, in eg `millibase` and `RTCbase`.
>• At some interval (eg, 10 seconds or a minute, in each case coincident with an RTC seconds-change) measure `millis()` and an RTC reading, in eg `millinow` and `RTCnow`.  Compute `RTCdeltaK` as the number of milliseconds from `RTCbase` to `RTCnow`.  Compute `millidelta` as `millinow-millibase`.
>• Whenever elapsed time in milliseconds is needed, compute `elapsedms = ((millis()-millibase)*RTCdeltaK)/millidelta`.

The above is an algorithm, and may need some adjustment before use as an implementation.  First, the `elapsedms` calculation can be arranged to avoid division, using a scaled multiplicative factor based on `millidelta`, `RTCdeltaK`, and some powers of 2.  Secondly, relatively constant clock drift is assumed.  If that assumption is incorrect, an average ratio with exponential decay could be used, instead of just a factor equivalent to `RTCdeltaK/millidelta`.

body:
If you are using a RTC a far better solution to use alarms.

I use `TimeAlarms` for this purpose

    #include <Time.h>        //http://www.arduino.cc/playground/Code/Time
    #include <Timezone.h>    //https://github.com/JChristensen/Timezone
    #include <TimeAlarms.h> //  Time alarms for use with Time library
    #include <DS1307RTC.h>   //http://www.arduino.cc/playground/Code/Time returns time as a time_t

then include code to do something. The following waits for the Minutes to rollover, then calls function `Repeats` every 30 seconds etc

    const int SampleRate = 30; // seconds >1

      Alarm.waitMinuteRollover();
      Alarm.timerRepeat(SampleRate, Repeats);   // timer for every SampleRate seconds
      Alarm.alarmRepeat(alarmTime, rolloverLogFile); // alarm to rollover LogFile (daily)

body:
Yours is a classical problem of _clock synchronization_. You have a
software clock (your program's idea of the current time) which you want
to keep in sync with a reference hardware clock (the RTC). This is
typically achieved by using a [phase-locked
loop](https://en.wikipedia.org/wiki/Phase-locked_loop), or PLL. It works
as follows:

* you measure the difference between your software clock's time and the
  reference time
* you adjust your software clock based on this measurement.

This is essentially what you are already doing, except that you are
fixing your clock by stepping it abruptly, whereas a PLL would usually
slew the clock to get it in sync progressively.

Stepping the clock has some undesirable effects: it makes the time
discontinuous and, more annoyingly, it can make it non-monotonic. I
would thus recommend you try to slew your clock instead.

Here is the approach I would try if I were in your shoes. I am assuming
you are using an Arduino Uno, or a similar AVR-based board with a 16-bit
Timer 1:

* configure Timer 1 in mode 4: CTC mode with TOP = OCR1A
* set the prescaler to 64 and OCR1A = 12499 in order to get a period of
  50 ms; TIMER1\_COMPA\_vect will be your data gathering interrupt
* configure your RTC to generate a 1 Hz output, and route this
  signal to the input capture pin ICP1 (pin 8 on the Uno)
* run the PLL logic inside TIMER1\_CAPT\_vect.

Since the RTC's 1 Hz period is a multiple of the timer period, you
would expect the timer's input capture unit to always capture the same
value. The difference between two consecutive captured values is thus a
direct measure of your clock's drift in units of 4 ppm
(4 µs/s). The ISR would be basically along these lines:

    ISR(TIMER1_CAPT_vect)
    {
        static uint16_t last_capture;
        uint16_t this_capture = ICR1;
        int16_t drift = this_capture - last_capture;
        last_capture = this_capture;

        // Reduce the drift modulo 12500 into [-6250, +6250).
        if (drift >= 6250) drift -= 12500;
        if (drift < -6250) drift += 12500;

        tune_clock(drift);
    }

where `tune_clock()` is your PLL algorithm responsible for slewing the
software clock.

Pay attention to the signedness of the variables. The subtraction of the
captured values should be done with unsigned numbers, _then_ the result
should be made signed.

------------------------------------------------------------------------

**Edit**: as suggested by James Waldby, I'll give here some suggestions
on the implementation of the PLL. It turns out it is not so simple:
_measuring_ a clock drift is easy, _predicting_ it is harder.

Let me restate the problem. You have a “good” clock: the RTC 1 Hz
signal, assumed to be perfect, but with a limited resolution of one
second. And you have a “bad” clock: Timer 1, which has a 4 µs resolution
but suffers from [frequency inaccuracy, instability and sensitivity to
temperature and supply voltage][arduino-frequency]. You want to combine
both clocks into a software clock which tracks the good clock yet has
the superior resolution of the bad clock.

I will use the following notations:

* t is the time from the reference clock (the RTC), assumed to be also
  the physical time
* n = ⌊t⌋ is the integer part of t, which is also the time when we last
  got an update from the RTC (a timer capture event)
* t′ is the time from the local clock (the Arduino timers)
* x = t′ − t is the local clock offset, measured by the ISR above at
  integer values of t; the physical time is given by t = t′ − x
* y = dx/dt is the local clock drift rate; it's a dimensionless quantity
  and typically less than 10−3 (i.e. less than 1 ms/s)
* xe(t) is the estimate, made by the software, of the offset x(t)
* ye(t) = dxe/dt is the estimate of the drift rate y(t)
* te = t′ − xe(te) is our software
  clock: a self-consistent estimate of t

The simplest solution, which is equivalent to the one you have in your
question, is to assume x stays constant until it is updated. Thus

xe(t) = x(n)
te = t′ − x(n)

In other words, we are just correcting for the last known offset. The
problem is, as stated before, that this gives a discontinuous time
scale.

A better solution is to try to _predict_ x(n+1), and linearly
interpolate between our previous and our current prediction, thus
building a continuous piecewise linear estimate of x:

xe(t) = xe(n) + (t−n)ye(n+½),
where ye(n+½) = xe(n+1) − xe(n)

From this, the estimated time can be solved for as:

te = n + (t′−xe(n)−n)/(1+ye(n+½))
≈ n + (t′−xe(n)−n)⋅(1−ye(n+½))

The factor 1/(1+ye(n+½)) ≈ (1−ye(n+½)) accounts
for the fact that the clock has drifted since the last update at t = n.

Now we are left with the problem of predicting x(n+1). There are
many possible approaches, and I will try to describe only a few.

## Simple PLL

One simple approach is to simulate an analog PLL with a first order
low-pass filter. Here is the first illustration of the Wikipedia article
on [phase-locked loop][]:

![Schematic of a PLL][]

Some translation is needed between this analog picture and the digital
domain: The phase comparator takes the difference between the measured
offset x(n) and our previous prediction xe(n). The low pass
filter is implemented as an exponentially weighted moving average. The
output of the filter is our estimate of the drift rate: ye.
The VCO is the formula for estimating te, which has the
built-in drift rate −ye. This could be translated to C++
roughly along these lines:

    struct {
        uint32_t n;  // time of last update
        float xe;    // estimate of offset at time n
        float ye;    // estimate of drift rate for t in [n ,n+1]
    } clock;

    const float tau = 60;  // low-pass filter time constant, in seconds
    const float K = 1;     // DC gain of the filter
    const float alpha = 1/(1+tau);

    // Called by the ISR.
    // y is (x[now] - x[1 second ago]) in units of 4 us.
    void tune_clock(int16_t y)
    {
        static float x;   // last known offset
        x += y * 4e-6;    // update known offset
        float xe = clock.xe + clock.ye;  // estimate of current offset

        // Update time.
        clock.n++;

        // Update our estimate of the drift rate.
        clock.ye += alpha*(K*(x-xe) - clock.ye);

        // Update or estimate of the offset.
        clock.xe = xe;
    }

    // Estimate the current time.
    float time()
    {
        float t_local = micros() * 1e-6;
        return clock.n + (t_local - clock.xe - clock.n) * (1 - clock.ye);
    }

Note that the code above is only meant as a guide. A good implementation
should use fixed-point instead of floats and should also be
rollover-safe.

The time constant of the filter should be chosen large enough to smooth
out the jitter caused by the 4 µs resolution, yet short enough to
closely track the frequency variations of the local clock. Ideally, it
should be close to the [Allan intercept][] of the x(n) time series.

This kind of PLL normally does a good job at tracking the reference
clock, but it has one drawback: it tends to carry a systematic offset.
Let's assume, for simplicity, that the drift rate is constant. Then it
can be easily seen that the steady state of the PLL carries an offset
error:

te − t = x − xe = y/K

where K is the DC gain of the filter. A large gain minimizes this error,
but it does so at the expense of stability. Too large a DC gain and the
PLL will spontaneously go into large oscillations.

I assume it should be possible to get rid of this systematic bias by
using more sophisticated filters, maybe something like a [PID][], but I
do not want to dive into the complexities of such filters.

## Simple linear extrapolation

Another way of estimating x(n+1), which does not suffer from systematic
bias, is to linearly extrapolate from the two last known values:

xe(n+1) = 2 x(n) − x(n−1)

This means we assume that the drift rate is constant on this
short time scale. The problem with this method is that it tends to
amplify the fluctuations due to the jitter. Assuming for example an
(overoptimistic) drift rate of 2 ppm, the measured offset will
alternate between having zero and 4 µs increments. The
extrapolation will predict every zero increment to be followed by
another zero increment, and every 4 µs increment to be followed by
another 4 µs increment, and thus it will always be wrong. The time
evolution would look as follows:

    t[s]    0   1   2   3   4   5   6   7   8   9  10
    x[µs]   0   0   4   4   8   8  12  12  16  16  20
    xₑ[µs]  0   0   0   8   4  12   8  16  12  20  16

## Brown's linear exponential smoothing

[Brown's method][Brown] is one of many linear extrapolation methods
meant to smooth-out noise in the data. It is based on running _twice_
the same low-pass filter on the input data:

    s1 = low_pass(x)   // first smoothing
    s2 = low_pass(s1)  // second smoothing

If τ is the time constant of the filter, then s1 is an
average of data which has, _on average_ the age τ, whereas s2
has the age 2τ. When can then, at time t, do a linear extrapolation by
running a straight line through the points (t−τ, s1) and
(t−2τ, s2). This gives the following algorithm for updating
the estimates of the offset and the drift rate:

    static float s1, s2;      // x smoothed once and twice
    s1 += alpha * (x - s1);   // update s1
    s2 += alpha * (s1 - s2);  // update s2

    // Update or estimate of the offset.
    clock.xe = xe;

    // Extrapolate to estimate next offset.
    xe = s1 + (s1-s2)*(tau+1)/tau;

    // Update our estimate of the drift rate.
    clock.ye = xe - clock.xe;

Here again, the optimal time constant should be of the order of the
Allan intercept. Note that the limit τ → 0 gives the simple
extrapolation of the previous section.

The figure below shows the performance of this algorithm on simulated
data. The simulated clock has a drift rate oscillating between 1.7 and
2.3 ppm, and its measured offset is rounded to the closest multiple of
4 µs. The line labeled “predicted (τ = 0)” is the simple
extrapolation of the previous section:

![Clock offset extrapolation](https://i.stack.imgur.com/g2mkJ.png)

Here, the large jitter of the simple extrapolation method is quite
obvious. On this simulated data, Brown's method works well with a time
constant on the order of 5 s. The frequency of a real clock would
change much more slowly, and a longer time constant would work better.

Now, all this is probably too general for your particular use case. I
didn't know when I started this edit it would lead me so far... If you
can tolerate more than, say, 10 µs of jitter, then the simple
extrapolation should be good enough. And if you only need the time at
t′-periodic intervals, this may enable some optimizations.

[arduino-frequency]: http://jorisvr.nl/article/arduino-frequency
[phase-locked loop]: https://en.wikipedia.org/wiki/Phase-locked_loop
[Schematic of a PLL]: https://upload.wikimedia.org/wikipedia/commons/thumb/d/db/Phase_locked_loop.svg/320px-Phase_locked_loop.svg.png
[Allan intercept]: http://www.slac.stanford.edu/comp/unix/package/rtems/src/ssrlApps/ntpNanoclock/theory.htm##allan

[PID]: https://en.wikipedia.org/wiki/PID_controller
[Brown]: https://en.wikipedia.org/wiki/Exponential_smoothing#Double_exponential_smoothing