message:
MPU-6050 + Arduino Micro + nRF24L01 FIFO overflow!

So I have an Arduino Micro, nRF24L01, and MPU-6050 all attached together and its transmitting information to another nRF24L01 on an Arduino Uno. The problem is that I keep getting FIFO overflow on the sending side. If I leave the sensor holding still it goes going for some time, but when I start moving the sensor around it halts, like it can't take that much data when the sensor is moving around. So I think its something with the code:

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

    // Include libraries necessary for the radios
    #include <SPI.h>
    #include <nRF24L01.h>
    #include <RF24.h>

    //set up name for serial communication of the radio
    RF24 radio(9, 10);

    // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
    // for both classes must be in the include path of your project
    #include "I2Cdev.h"

    #include "MPU6050_6Axis_MotionApps20.h"
    //#include "MPU6050.h" // not necessary if using MotionApps include file

    // Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
    // is used in I2Cdev.h
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
        #include "Wire.h"
    #endif

    // class default I2C address is 0x68
    // specific I2C addresses may be passed as a parameter here
    // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
    // AD0 high = 0x69
    MPU6050 mpu;
    //MPU6050 mpu(0x69); // <-- use for AD0 high

    /* =========================================================================
       NOTE: In addition to connection 3.3v, GND, SDA, and SCL, this sketch
       depends on the MPU-6050's INT pin being connected to the Arduino's
       external interrupt #0 pin. On the Arduino Uno and Mega 2560, this is
       digital I/O pin 2.
     * ========================================================================= */

    /* =========================================================================
       NOTE: Arduino v1.0.1 with the Leonardo board generates a compile error
       when using Serial.write(buf, len). The Teapot output uses this method.
       The solution requires a modification to the Arduino USBAPI.h file, which
       is fortunately simple, but annoying. This will be fixed in the next IDE
       release. For more info, see these links:

       http://arduino.cc/forum/index.php/topic,109987.0.html
       http://code.google.com/p/arduino/issues/detail?id=958
     * ========================================================================= */

    // uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
    // quaternion components in a [w, x, y, z] format (not best for parsing
    // on a remote host such as Processing or something though)
    //#define OUTPUT_READABLE_QUATERNION

    // uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
    // (in degrees) calculated from the quaternions coming from the FIFO.
    // Note that Euler angles suffer from gimbal lock (for more info, see
    // http://en.wikipedia.org/wiki/Gimbal_lock)
    //#define OUTPUT_READABLE_EULER

    // uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
    // pitch/roll angles (in degrees) calculated from the quaternions coming
    // from the FIFO. Note this also requires gravity vector calculations.
    // Also note that yaw/pitch/roll angles suffer from gimbal lock (for
    // more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
    #define OUTPUT_READABLE_YAWPITCHROLL

    // uncomment "OUTPUT_READABLE_REALACCEL" if you want to see acceleration
    // components with gravity removed. This acceleration reference frame is
    // not compensated for orientation, so +X is always +X according to the
    // sensor, just without the effects of gravity. If you want acceleration
    // compensated for orientation, us OUTPUT_READABLE_WORLDACCEL instead.
    //#define OUTPUT_READABLE_REALACCEL

    // We are using this output to obtain global coordinate acceleration
    //and euler angles (coordinate system irrelevant)
    #define OUTPUT_READABLE_WORLDACCEL_AND_GYRO

    // uncomment "OUTPUT_TEAPOT" if you want output that matches the
    // format used for the InvenSense teapot demo
    //#define OUTPUT_TEAPOT

    #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
    bool blinkState = false;

    // MPU control/status vars
    bool dmpReady = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus;   // holds actual interrupt status byte from MPU
    uint8_t devStatus;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q;           // [w, x, y, z]         quaternion container
    VectorInt16 aa;         // [x, y, z]            accel sensor measurements
    VectorInt16 aaReal;     // [x, y, z]            gravity-free accel sensor measurements
    VectorInt16 aaWorld;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity;    // [x, y, z]            gravity vector
    float euler[3];         // [psi, theta, phi]    Euler angle container
    float ypr[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };

    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================

    volatile bool mpuInterrupt = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady() {
        mpuInterrupt = true;
    }

    // ================================================================
    // ===                      INITIAL SETUP                       ===
    // ================================================================

    void setup() {
        // join I2C bus (I2Cdev library doesn't do this automatically)
        #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
            Wire.begin();
            TWBR = 12; // 400kHz I2C clock (200kHz if CPU is 8MHz). Comment this line if having compilation difficulties with TWBR.
        #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
            Fastwire::setup(400, true);
        #endif

        // initialize serial communication
        // (115200 chosen because it is required for Teapot Demo output, but it's
        // really up to you depending on your project)
        //Serial.begin(115200);
        //while (!Serial); // wait for Leonardo enumeration, others continue immediately

        // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
        // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
        // the baud timing being too misaligned with processor ticks. You must use
        // 38400 or slower in these cases, or use some kind of external separate
        // crystal solution for the UART timer.

        // Initialize radio communication
        radio.begin();
        radio.setRetries(15, 15);
        radio.openWritingPipe(0xF0F0F0F0A1LL);

        radio.stopListening();

        Serial.begin(115200);

        // initialize device
        Serial.println(F("Initializing I2C devices..."));
        mpu.initialize();

        // verify connection
        Serial.println(F("Testing device connections..."));
        Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));

        // wait for ready
        /*
        Serial.println(F("\nSend any character to begin DMP programming and demo: "));
        while (Serial.available() && Serial.read()); // empty buffer
        while (!Serial.available());                 // wait for data
        while (Serial.available() && Serial.read()); // empty buffer again
        */

        // load and configure the DMP
        Serial.println(F("Initializing DMP..."));
        devStatus = mpu.dmpInitialize();

        // supply your own gyro offsets here, scaled for min sensitivity
        mpu.setXGyroOffset(54);
        mpu.setYGyroOffset(15);
        mpu.setZGyroOffset(33);
        mpu.setZAccelOffset(1613); // 1688 factory default for my test chip
        mpu.setXAccelOffset(-4009);
        mpu.setYAccelOffset(332);

        // make sure it worked (returns 0 if so)
        if (devStatus == 0) {
            // turn on the DMP, now that it's ready
            Serial.println(F("Enabling DMP..."));
            mpu.setDMPEnabled(true);

            // enable Arduino interrupt detection
            Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
            attachInterrupt(0, dmpDataReady, RISING);
            mpuIntStatus = mpu.getIntStatus();

            // set our DMP Ready flag so the main loop() function knows it's okay to use it
            Serial.println(F("DMP ready! Waiting for first interrupt..."));
            dmpReady = true;

            // get expected DMP packet size for later comparison
            packetSize = mpu.dmpGetFIFOPacketSize();
        } else {
            // ERROR!
            // 1 = initial memory load failed
            // 2 = DMP configuration updates failed
            // (if it's going to break, usually the code will be 1)
            Serial.print(F("DMP Initialization failed (code "));
            Serial.print(devStatus);
            Serial.println(F(")"));
        }

        // configure LED for output
        pinMode(LED_PIN, OUTPUT);

    }

    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================

    void loop() {
        // if programming failed, don't try to do anything
        if (!dmpReady) return;

        // wait for MPU interrupt or extra packet(s) available
        while (!mpuInterrupt && fifoCount < packetSize) {
            // other program behavior stuff here
            // .
            // .
            // .
            // if you are really paranoid you can frequently test in between other
            // stuff to see if mpuInterrupt is true, and if so, "break;" from the
            // while() loop to immediately process the MPU data
            // .
            // .
            // .

        }

        // reset interrupt flag and get INT_STATUS byte
        mpuInterrupt = false;
        mpuIntStatus = mpu.getIntStatus();

        // get current FIFO count
        fifoCount = mpu.getFIFOCount();

        // check for overflow (this should never happen unless our code is too inefficient)
        if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
            // reset so we can continue cleanly
            mpu.resetFIFO();
            char fifo_text[]="FIFO overflow!";
            radio.write(&fifo_text, sizeof(fifo_text));
            Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen frequently)
        } else if (mpuIntStatus & 0x02) {

            // wait for correct available data length, should be a VERY short wait
            while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();

            // read a packet from FIFO
            mpu.getFIFOBytes(fifoBuffer, packetSize);

            // track FIFO count here in case there is > 1 packet available
            // (this lets us immediately read more without waiting for an interrupt)
            fifoCount -= packetSize;

            #ifdef OUTPUT_READABLE_QUATERNION
                // display quaternion values in easy matrix form: w x y z
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                Serial.print("quat\t");
                Serial.print(q.w);
                Serial.print("\t");
                Serial.print(q.x);
                Serial.print("\t");
                Serial.print(q.y);
                Serial.print("\t");
                Serial.println(q.z);
            #endif

            #ifdef OUTPUT_READABLE_EULER
                // display Euler angles in degrees
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetEuler(euler, &q);
                Serial.print("euler\t");
                Serial.print(euler[0] * 180/M_PI);
                Serial.print("\t");
                Serial.print(euler[1] * 180/M_PI);
                Serial.print("\t");
                Serial.println(euler[2] * 180/M_PI);
            #endif

            #ifdef OUTPUT_READABLE_YAWPITCHROLL
                // display Euler angles in degrees
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetGravity(&gravity, &q);
                mpu.dmpGetYawPitchRoll(ypr, &q, &gravity);
                Serial.print("ypr\t");
                Serial.print(ypr[0] * 180/M_PI);
                Serial.print("\t");
                Serial.print(ypr[1] * 180/M_PI);
                Serial.print("\t");
                Serial.println(ypr[2] * 180/M_PI);
            #endif

            #ifdef OUTPUT_READABLE_REALACCEL
                // display real acceleration, adjusted to remove gravity
                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetAccel(&aa, fifoBuffer);
                mpu.dmpGetGravity(&gravity, &q);
                mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
                Serial.print("areal\t");
                Serial.print(aaReal.x);
                Serial.print("\t");
                Serial.print(aaReal.y);
                Serial.print("\t");
                Serial.println(aaReal.z);
            #endif

            #ifdef OUTPUT_READABLE_WORLDACCEL_AND_GYRO
                // display initial world-frame acceleration, adjusted to remove gravity
                // and rotated based on known orientation from quaternion

                mpu.dmpGetQuaternion(&q, fifoBuffer);
                mpu.dmpGetAccel(&aa, fifoBuffer);
                mpu.dmpGetGravity(&gravity, &q);
                mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
                mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
                //Serial.print("aworld\t");
                //Serial.print(aaWorld.x);
                //Serial.print("\t");
                //Serial.print(aaWorld.y);
                //Serial.print("\t");
                //Serial.print(aaWorld.z);
                //radio.write(&aaWorld.z,sizeof(aaWorld.z));
                //String x=String(aaWorld.x);
                //const char*text=x.c_str();

                /*
                char x_text[]="X acceleration";
                radio.write(&x_text, sizeof(x_text));
                */
                typedef struct Value {
                  int x;
                  int y;
                  int z;
                  int e0;
                  int e1;
                  int e2;
                } Value;

                Value value;

                value.x=aaWorld.x;
                value.y=aaWorld.y;
                value.z=aaWorld.z;

                /*
                float acceleration[3];
                acceleration[0]=aaWorld.x;
                acceleration[1]=aaWorld.y;

                char x_value[8];
                char y_value[8];

                dtostrf(aaWorld.x,5,2,x_value);
                dtostrf(aaWorld.y,5,2,y_value);
                //char* coordinates[]={x_value,y_value};
                //char* coordinates[]={x_value,y_value};
                int coordinates[]={aaWorld.x,aaWorld.y};
                //radio.write(&y_value, sizeof(y_value));
                //radio.write(&coordinates, sizeof(coordinates));
                */

                //Serial.println(aaWorld);
                mpu.dmpGetEuler(euler, &q);

                //Serial.print("euler\t");
                int euler_0=euler[0] * 180/M_PI;
                value.e0=euler_0;
                //Serial.print("\t");
                int euler_1=euler[1] * 180/M_PI;
                value.e1=euler_1;
                //Serial.print("\t");
                int euler_2=euler[2] * 180/M_PI;
                value.e2=euler_2;
                //euler=(int[3])euler;
                //int euler[]={1,2,3};
                //Serial.write(euler*180/M_PI,3);
                //delay(50);

                radio.write(&value, sizeof(value));
                Serial.println(aaWorld.z);

            #endif
        /*
            #ifdef OUTPUT_TEAPOT
                // display quaternion values in InvenSense Teapot demo format:
                teapotPacket[2] = fifoBuffer[0];
                teapotPacket[3] = fifoBuffer[1];
                teapotPacket[4] = fifoBuffer[4];
                teapotPacket[5] = fifoBuffer[5];
                teapotPacket[6] = fifoBuffer[8];
                teapotPacket[7] = fifoBuffer[9];
                teapotPacket[8] = fifoBuffer[12];
                teapotPacket[9] = fifoBuffer[13];
                Serial.write(teapotPacket, 14);
                teapotPacket[11]++; // packetCount, loops at 0xFF on purpose
            #endif
    */
            // blink LED to indicate activity
            blinkState = !blinkState;
            digitalWrite(LED_PIN, blinkState);
        }
    }

body:
I found the problem, I had to comment `out_put_readable_realaccel`. So it had to be `//#define OUTPUT_READABLE_REALACCEL` because it was running the yaw pitch and roll and the real acceleration at the same time so it was overloading.

Posted on behalf of the OP.


sender: user

message:
What is an easy way to power a 3.3v BMP-180 barometer board from a 5v Arduino Nano?

Scenario:
-
  I have a functioning weather station (temp/humid, MQ-2 smoke sensor, anemometer), and want to add a barometer.  The weather station is outside, linked to my inside display and RTC by the I2c&Power modules and ethernet cable.  The cable supplies 12v and I use a small converter to provide the 5v to run the I2c&Power board and the rest.

  So I have 12v and 5v available out at the weather box.

  Inside along with the RTC and LCD display I have a 2-port I2C&Power which will be used in the future (with the new pgpio library) to feed the info to an Rpi3 to create a web page to show changes over time.

  The barometer module I bought is the BMP-180.  It is nice and tiny and looks perfect for the job, but the instructions all over the web tell me that it will burn up if powered by 5V.  The Arduino Nano does not have a 3.3v output pin like the Uno does.

Q:  What is the easiest way to accomplish adding this 3.3v board to the weather station?

sender: assistant

body:
Here is the solution I settled on:  a small part that will step 5 volts down to 3.3 volts.  The price is right, but it will be shipped by the slow boat so will take a month or so to receive.

5Pcs 5V to 3.3V DC-DC Step-Down Power Supply Buck Module AMS1117 LDO 800MA

http://www.ebay.com/itm/5Pcs-5V-to-3-3V-DC-DC-Step-Down-Power-Supply-Buck-Module-AMS1117-LDO-800MA-/261983164332

It has 3 pins - Vin, Vout, GND.    Easy to hook up.

Upvote to everybody for the discussion.


body:
Consider attaching your +5V supply to a USB plug, and using that to power the Nano via its USB socket.

When the Nano is powered via its USB socket, the CH340 or FTDI FT232 supply  up to 50mA of 3.3V power to the 3V3 pin located between Aref and d13.  See for example [3v3 output from FTDI chip on Arduino Nano 3](http://forum.arduino.cc/index.php?topic=177059.0) at arduino.cc.

Actually, that thread apparently says the 3V3 is available no matter how the board is powered; you may want to run some tests and measurements.  The only test I ran was to measure about 3.2 V at the 3V3 pin when a clone Nano 3 with CH340 was connected to a USB-power adapter.


message:
Reverse engineering of a bluetooth sensor

I have a problem.
I'm trying to trigger some events with Arduino using some bluetooth LE sensor by a chinese manufacturer, Kaipule. I buy this sensor on Alibaba and I'm trying to understand how can I interface them in my sketch.

They are magnetic contact sensors and I know that they have just the BLE broadcasting mode (no GATT, profile etc): they send information when I open the contact or I close the contact.

I try to scan them with a BLE scanner and this is the log

    kCBAdvDataIsConnectable : 0
    Local Name : iSensor
    Manufacturer Data : <beca2c02 4602f9f7>

I know that:

1) the scanner can see the sensor just when I open/close the contact to save battery, so the sensor broadcast data just when it need.

2) every hour the sensor send a status signal

3) every time I open and close the contact the code change a little. Here is a sequence

    <beca2c02 46025856> - > open
    <beca2c02 46005955> - > close
    <beca2c02 46025a58> - > open
    <beca2c02 46005b57> - > close
    <beca2c02 46025c5a> - > open
    <beca2c02 46005d59> - > close
    <beca2c02 46025e5c> - > open
    <beca2c02 46005f5b> - > close

etc

4) The first part of the code is the identification of the sensor.

[![my sensor][1]][1]

3) From the changing code I assume that 2 is the status open, 0 is the status close and I see also a pattern for other bytes but I cannot understand why for example there is a rolling code.

I have the paper the company send to me, but I cannot find any useful reference.

[Wireless sensor 1][2]
[Wireless sensor 2][3]

  [1]: https://i.stack.imgur.com/RbiVf.jpg
  [2]: https://forum.dday.it/uploads/default/original/1X/084a35afaefa0753541a18bda6f97b2d640e13a3.pdf
  [3]:
https://forum.dday.it/uploads/default/original/1X/1c3502099d8eeca36b57187511f8516407530d05.pdf

body:
Looking at the datasheet, I interpreted it as:

**Byte 1 - 0x46**

Indicating this is a unidirectional device (bit7=0) that uses fixed time sending (bit 6=1 *which doesn't seem correct*) and it is of type 'door contact' (bits 0-5=0x06)

**Byte 2 - 0x00/0x02**

Indicating that the door is open or closed (bit 1 = 0 or 1). I also **think** that it indicates there is 'enough battery power' (bit 2 = 0), and the 'anti-tamper' has not been activated (bit 0 = 0)

**Byte 3 - 0xXX**

This is the 'Frame ID' - counting up for 0x40, to 0x5F then looping ?

**Byte 4 - 0xXX**

Checksum.

I'd do three things to test this theory:

 1. Run the battery down a lot and see if the battery power indicator changes (byte 2, bit 2).
 2. Open the case and see if the 'anti-tamper' bit changes (byte 2, bit 0)
 3. Do sufficient switching to determine if byte 3 loops around as expected.

This these don't work out then you're likely looking at a different model.


message:
arduino not loading library

I am receiving a compilation error from

    #include <HX711.h>

The error is

    fatal error: HX711.h: No such file or directory

However, C:\Users\user\Documents\Arduino\libraries\HX711 is there and has the correct files in it.
Sketch -> Include Library -> Manage libraries says that HX711 is installed. Strange thing is that I have another sketch that uses this library and it compiles. It uses quotes instead of angle brackets (which is strange because HX711.h is not in the same directory) and it works.
I have tried both quotes and angle brackets.

EDIT: I am really sorry about typing "define" instead of "include" into the question my only excuse was that it was late.
I copied the library directory to:

    C:\Program Files (x86)\Arduino\libraries

and the problem remains.

I now have the HX711 directory in both the Arduino program files and the user directories and it still complains about it. The only way I can get it to compile is to place the hx711.h & hx711.cpp files directly into the sketch directory and change the line to #include "HX711.h"

EDIT:
Running Arduino 1.6.5 on Windows 8.1 64bit

body:
Is the line of code really

    #define <HX711.h>

If it is then replace `<` with `<` and that will fix it.

If the include statement has angle brackets <> around it then the file should be located in the system library folder, `C:\Program Files\Arduino\Libraries` on Windows.  I think there can now be a user library folder as well `C:\Users\PHemans\Documents\Arduino\Libraries` and I _think_ that the <> include will pick up from here too.

If the file is in you local folder (same place as the ino) then you should use "" the file name.

It is also possible that what you are seeing is not what the compiler is seeing, so deleting the whole line and then retyping it can sometimes work, as can checking the file endings and encodings using a tool like Notepad++.


body: You're using `#define` when it should be `#include`.


message:
Problem with microSD SPI mode in AVR

I'm trying to read a microSD block. But I don't know why it doesn't work.

I do:

    CS_UP;
    for(uint8_t i = 0; i <14; i++){ /* Send 74+ clocks */
        spi_tranceiver(0xff);
    }
    _delay_ms(1); /* Wait 1 ms */

    //CS_UP;

    /* Initizalize microSD */
    put_string("Go to idle state\n");
    while (Reset_Card() != 0x01) // Go to idle state
        ;

    put_string("Send IF COND\n");
    while (Send_CMD8() != 0x01) // SEND IF COND
        ;

    put_string("Send ACMD41 and CMD55\n");
    for (int i = 0; i<100; i++)
        while (Send_CMD55() && Send_ACMD41())
            ;

    setBlockLen(); // Set block read in 512 bytes
    CS_DOWN;
    put_string("\nConfigure finished correctly\n");

And then I just call:

    readSingleBlock(0x00, &buf)

readSingleBlock is defined as follows:

    uint8_t readSingleBlock(uint32_t block_address, unsigned char *buf)
    {
        int i;

        block_address = block_address << 9;

        CS_UP;
        while (0x00 != sdsc_command(READ_SINGLE_BLOCK, block_address))
            ;

        while (0xfe != spi_rx ())
            ;

        for (i = 0; i < 512; i ++ ){
            //buf [ i ] = spi_rx();
            put_int(spi_rx());
            put_string("\n");
        }
        spi_rx();
        spi_rx();
        CS_DOWN;

        //for (i = 0; i<512; i++) put_int(buf[i]);

The problem is that the printout is:

0 0 0 ..(zeros).. 128 255 255 255 12 255 255 255 0 8 0 0 0 72 59 ..(zeros).. 85 170

Did somebody encounter this problem?

Do you have some suggestions?

body:
I formated the SD card, and then work correctly

Thanks!


message:
Connection ESP8266 to ESP8266 Client Server can't Connect, Help me?

I have a project to connecting dual esp8266 using client server method, my expectation the server can get command from user from web request, and the request will be forward to client from server to turn on led. But the connection from server always failed

I'm using ESP-12F and programming using Arduino IDE

the code of server :

    //--------------------------------------------------------------------------
      #include <ESP8266WiFi.h>
    //--------------------------------------------------------------------------
    // Membuat Variabel Autentikasi
    //--------------------------------------------------------------------------
      const char* ssid = "master-sport";
      const char* password = "1234567890";
    //--------------------------------------------------------------------------
    // Mengatur IP Address
    //--------------------------------------------------------------------------
      IPAddress CLIENTA(192,168,4,100);
    //--------------------------------------------------------------------------
    // Create an instance of the server
    // specify the port to listen on as an argument
    //--------------------------------------------------------------------------
      WiFiServer server(80);
      WiFiClient client;
    //===========================================================================
      void setup() {
       Serial.begin(115200);
       delay(10);

      // Mengatur WiFi ----------------------------------------------------------
       Serial.println();
       Serial.print("Configuring access point...");

       WiFi.mode(WIFI_AP);
       WiFi.softAP(ssid, password);

      // Start the server -------------------------------------------------------
       server.begin();
       Serial.println("Server dijalankan");

      // Print the IP address ---------------------------------------------------
       Serial.println(WiFi.localIP());
     }

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

      void loop() {
      // Check if a client has connected ----------------------------------------
        client = server.available();
        if (!client) {
        return;
      }

      // Wait until the client sends some data ----------------------------------
       Serial.println("new client");
       while(!client.available()){
         delay(1);
      }

      // Read the first line of the request -------------------------------------
       String req = client.readStringUntil('\r');
       Serial.println(req);
       client.flush();

      // Match the request ------------------------------------------------------
       const char* host;
       int val;
       if (req.indexOf("/sr/0") != -1){
          host = "sa";
          val = 0;
        }
       else if (req.indexOf("/sr/1") != -1){
          host = "sa";
          val = 1;
        }
       else {
         Serial.println("invalid request");
         client.stop();
         return;
        }

       client.flush();
       Serial.println("Client disonnected");

      // Pengiriman data ke client -----------------------------------------------
       int value  = 0;
       delay(5000);
       ++value;

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

      // Memebuat TCP Connection Menggunakan WiFiClient --------------------------
       const int httpPort = 80;
       if (!client.connect(CLIENTA, httpPort)) {
         Serial.println("connection failed");
         return;
       }

      // Membuat URL untuk dikirimkan -------------------------------------------
       String url = host;
       url += "/";
       url += val;

       Serial.print("Requesting URL: ");
       Serial.println(url);

      // Mengirimkan Request ke Client ------------------------------------------
       client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                   "Host: " + CLIENTA + "\r\n" +
                   "Connection: close\r\n\r\n");
       unsigned long timeout = millis();
       while (client.available() == 0) {
         if (millis() - timeout > 5000) {
           Serial.println(">>> Client Timeout !");
           client.stop();
           return;
        }
      }

      // Melihat semua line balasan dari server dan menampilkan di Serial -------
       while(client.available()){
         String line = client.readStringUntil('\r');
         Serial.print(line);
       }

       Serial.println();
       Serial.println("closing connection");
    }
    //=============================================================================
Client code :

    //--------------------------------------------------------------------------
      #include <ESP8266WiFi.h>
      #include <Adafruit_NeoPixel.h>
      #ifdef __AVR__
      #include <avr/power.h>
      #endif
      #define PIN 13
    //--------------------------------------------------------------------------
    // Membuat Variabel Autentikasi
    //--------------------------------------------------------------------------
      const char* ssid = "master-sport";
      const char* password = "1234567890";
    //--------------------------------------------------------------------------
    // Mengatur IP Address
    //--------------------------------------------------------------------------
      IPAddress IP(192,168,4,100);
      IPAddress NETMASK(255,255,255,0);
      IPAddress NETWORK(192,168,4,1);
    //--------------------------------------------------------------------------
    // Create an instance of the server
    // specify the port to listen on as an argument
    //--------------------------------------------------------------------------
      WiFiServer server(80);
    //--------------------------------------------------------------------------
    // Menasukan LED RGB
    //--------------------------------------------------------------------------
      Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
    //===========================================================================
      void setup() {
       Serial.begin(115200);
       delay(10);

      // Connect to WiFi network ------------------------------------------------
       Serial.println();
       Serial.println();
       Serial.print("Connecting to ");
       Serial.println(ssid);

      // Mengatur WiFi ----------------------------------------------------------
       WiFi.mode(WIFI_STA);
       WiFi.begin(ssid, password);
       WiFi.config(IP, NETMASK, NETWORK);

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

      // Start the server -------------------------------------------------------
       server.begin();
       Serial.println("Server dijalankan");

      // Menjalankan LED RGB ----------------------------------------------------
       strip.begin();
       strip.show();

      // Print the IP address ---------------------------------------------------
       Serial.println(WiFi.localIP());
     }

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

      void loop() {
      // Check if a client has connected ----------------------------------------
        WiFiClient client = server.available();
        if (!client) {
        return;
      }

      // Wait until the client sends some data ----------------------------------
       Serial.println("new client");
       while(!client.available()){
         delay(1);
      }

      // Read the first line of the request -------------------------------------
       String req = client.readStringUntil('\r');
       Serial.println(req);
       client.flush();

      // Match the request ------------------------------------------------------
       int val;
       if (req.indexOf("/sa/0") != -1){
          strip.setPixelColor(4,0x000000); //LED menjadi mati -------------------
          strip.show();
        }
       else if (req.indexOf("/sa/1") != -1){
          strip.setPixelColor(4, 0xFF0000); //LED menjadi merah -----------------
          strip.show();
        }
       else {
         Serial.println("invalid request");
         client.stop();
         return;
        }

       client.flush();
       Serial.println("Client disonnected");
    }

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

whats wrong that code ?

body:
You do not need 2 ESPs, one is enough. Here you are the code so you can turn on the NeoPixel using web interface:

    #include <ESP8266WiFi.h>
    #include <WiFiClient.h>
    #include <ESP8266WebServer.h>

    IPAddress ip(192,168,1,81);         // choose IP address
    IPAddress subnet(255,255,255,0);

    ESP8266WebServer server(80);

    void handleRoot() {
      String page = "<!DOCTYPE html>\n";

      page += "\n\n
Some heading

Generated by ESP8266\n\n";
      server.send(200, "text/html", page);
    }

    // what to do when accessed through http://ip_address/something_undefined
    void handleNotFound(){
      String message = "File not found\n\n";
      message += "URI: ";
      message += server.uri();
      message += "\nMethod: ";
      message += (server.method() == HTTP_GET)?"GET":"POST";
      message += "\nArguments: ";
      message += server.args();
      message += "\n";
      for (uint8_t i=0; i<server.args(); i++){
        message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
      }
      server.send(404, "text/plain", message);
    }

    void setup(void){
      Serial.begin(74880);                      // so you can see debug messages automatically sent by ESP8266
      WiFi.mode(WIFI_AP);
      WiFi.softAPConfig(ip, ip, subnet);        // declared as: bool softAPConfig (IPAddress local_ip, IPAddress gateway, IPAddress subnet)
      WiFi.softAP("SOME_NAME", "password", 7);  // network name, network password, wifi channel

      IPAddress myIP = WiFi.softAPIP();
      Serial.println();
      Serial.print("AP IP address: ");
      Serial.println(myIP);

      server.on("/", handleRoot);               // what to do when accessed through browser using http://IP_address

      // what to do when accessed through http://ip_address/test
      server.on("/test", [](){
        server.send(200, "text/plain", "This is another page");
      });

      server.on("/sa/1", [](){
        // ... <-- put here the code for NeoPixel = on
        server.send(200, "text/html", "NeoPixel is now on");
      });

      server.on("/sa/0", [](){
        // ... <-- put here the code for NeoPixel = off
        server.send(200, "text/html", "NeoPixel is now off");
      });

      server.onNotFound(handleNotFound);

      server.begin();
      Serial.println("HTTP server started...");
    }

    void loop(void){
      server.handleClient();
    }

Now you can use `xx.xx.xx.xx/sa/1` and `xx.xx.xx.xx/sa/0` (where xx.xx.xx.xx is an IP address you've chosen) to turn on/off the NeoPixel.

Just add the Adafruit library for controlling NeoPixel and copy the NeoPixel setup and the code to turn it on/off from your code #2 to the appropriate places (I marked the place where to put the code to turn the NeoPixel on/off with the comments).

If you really want to add another ESP8266 then you have to set it up as a server using the same code - just change the `network name`, `password` & `IP address` and add sending GET request from your first ESP to the second.


message:
Is the MKS GEN V1.2 compatible with Arduino IDE as Arduino MEGA Board?

I need to do a Servo controller using Arduino and I have a spare MKS GEN V1.2 board right now, looking at the documentation from here http://reprap.org/wiki/MKS_GEN it seems this board is actually an Arduino board which can be programmed with the Arduino IDE.

Is this a correct observation that the MKS GEN V1.2 board is, in fact, a Arduino MEGA board internally?

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

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

body:
> It features an onboard ATmega2560.

This means that it is *internally* compatible with the Arduino Mega 2560. This does not mean that it is *completely* compatible with such since of course there is no way to use Mega shields with the board. This also means that there may be a core that provides *better* facility with the board, supporting its connections (LCD, positioning, heater/fan, etc.) better than the generic Mega core would.


message:
SIM800L always returns +CREG: 0,2

I'm using a SIM800L module, and I am checking the status of my network with the `AT+CREG?` command.

However, it always returns the same 0,2:

    0 -> disable network registration unsolicited result code

    2 -> not registered, but ME is currently searching a new operator to register to

How do I activate 2G or 3G network?

body:
* It can take a while to register - sometimes several minutes. Have you left it after power-up for enough time?

* If your operator has no signal in your area it will never register. National roaming is normally disabled. If you have national roaming available you will have to manually connect to another operator.

* Check that your modem can see your operator with `AT+COPS=?`


message:
Detecting a 2.8ms pulse using a Arduino Uno

I am working on a project for knowing the position of a DC motor which has a hall sensor built into it. I am a newbie into programming using the Arduino Uno R3. After some forum search and self checks, I cannot pass this hurdle. I hope I can frame the questions properly here.

My Problem: The DC motor hall sensor sends out 2 high pulse of 11.3V - 13V with a duration of 2.8ms for each revolution. My Arduino interrupt pin doesn't read the high pulse as it gives me "0" count after motor spin (I run 50 loops and results remain the same).

[![Interupt pin asssigment with function call][1]][1]

On my breadboard, I use a voltage divider to reduce hall-effect ouput from max 13V to 5V so that the Arduino pin 2 can read rising voltage when it jumps to 5V (low should be 2.5V).

Couple of things I noted during the motor spin -

a) The `millis()` function returns 79-81ms per sketch run

b) The same hall sensor output if connected to analog pin reads 580,590,590,1001, 1012, 580, 580.. etc. I cannot gauge position of the motor by using these values as they are inconsistent on the way up Vs. way down.

I have attached analog readings while going up and down in snap shot below:
[![enter image description here][2]][2]
2 questions I have:

1. Why is the pin 2 not detecting a high pulse? will it not be able to read 2.8ms durations because of motor speed (9.5 rev/s or 570rpm)?
2. Is it possible to gauge anything from Analog read function? Am I missing something?

Thanks in advance for all responses.. Any questions regarding the circuit, I will be more than happy to post them.

  [1]: https://i.stack.imgur.com/z3mh0.png
  [2]: https://i.stack.imgur.com/RS9u1.png

body:
First, better to see whole source and schematics.

"Why is the pin 2 not detecting"

Check:
1. Hall sensor connected to Pin 2

2. pulses variable declared as volatile.

3. Check if internal pull up resistor setup consistent with hall sensor connection.

4. Check that Hall sensor's lowest signal voltage is below 0.3 VCC (you said 5V, so it should drop below 1.5V), BTW 580 - the lowest analog value you showed means 2.83V

5. Check you are not using nointerrupt();

"Is it possible to gauge anything from Analog read function? Am "

Yes.
Analog read takes about 0.1 ms in default setup, so should make at least 1000 reads per second to catch peak.

So,
Easiest way is to choose some value like 600, when analog read is above mark it as Rising when it drops below mark is Falling.
More complicated ways will include some training and hysteresis to improve detection.

Also I suggest to use voltage limiter instead of voltage divider. This gives better detection.


body:
All,

Here is the code:

    int flag = 1;
    int speedo = 255;
              int counter =0; //counts the number of revolutions
              int timeu=0;
              int timed=0;
              int Voltmeasure=0;
              int times=0;
              volatile unsigned int pulses=0; //pulse counter
              bool upcount=false;
              bool downcount=false;
              unsigned int timeold=0;
              int difference=0;

              void count()
              {
                if(upcount==true)
                  pulses++;
                  else if (downcount==true)
                   pulses--;
              }

              void setup()
              {
                // initialize serial communication:
                Serial.begin(9600);
                pinMode(11,OUTPUT);
                pinMode(12,OUTPUT);
                pinMode(13,OUTPUT);
                pinMode(2, INPUT);
                pinMode(3, INPUT);
                attachInterrupt(digitalPinToInterrupt(2),count, RISING);
              }
              void stopmotor()
              {
                digitalWrite(12,HIGH);
                digitalWrite(13,HIGH);
              }
              void motorCCW()
              {
                analogWrite(11,speedo);
                digitalWrite(12,HIGH);
                digitalWrite(13,LOW);
              }
              void motorCW()
              {
                analogWrite(11,speedo);
                digitalWrite(12,LOW);
                digitalWrite(13,HIGH);
              }

              void loop()
              {
                  if(flag==1)
                  {
                    delay(2000); //wait for 2 seconds to start motor
                    flag=2;
                  }

                //first run motor moves down
                    if (counter<16 && flag==2)
                    {
                      motorCW(); //moving up

                      //Reading Hall-sensor pulses- using analog signal
                      Voltmeasure = analogRead(A3);
                      Serial.print("CW Voltmeasure = ");
                      Serial.print(Voltmeasure);
                      Serial.println();

                      //Reading Hall-sensor pulses - using interuppt signal
                      upcount=true;

                      //counting the number of high pulse
                      if (Voltmeasure>700 && times==0)
                      {
                        counter++; times=1;
                      }
                      else if (Voltmeasure<610)
                        times=0;

                      //timer for number of loops
                      timeu++;
                      Voltmeasure=0;

                      if (timeu==70||counter==16) //move by 70 cycles or until counter is 16
                      {
                        stopmotor();
                        upcount=false;
                        timeu=0;
                        times=0;
                        Serial.print("High-point is reached - Travel complete");
                        Serial.println();
                        delay(2000); //delay by 2 seconds
                        flag=3;
                      }
                    }

                    if (counter>0 && flag==3)
                    {
                      delay(2000); //pause before next run
                      motorCCW();

                      //Reading Hall-sensor pulses - using analog signal
                      Voltmeasure = analogRead(A3);
                      Serial.print("CCW Voltmeasure = ");
                      Serial.print(Voltmeasure);
                      Serial.println();

                      //Reading Hall-sensor pulses - using interuppt signal
                      downcount=true;

                     //counting the number of high pulse
                      if (Voltmeasure>700)
                      {
                        counter--; times=1;
                      }
                      else if (Voltmeasure<610)
                        times=0;
                      timed++;
                      Voltmeasure=0;

                      if (timed==70||counter==0) //move by 70 cycles or until counter is 0
                      {
                        stopmotor();
                        downcount=false;
                        timed=0;
                        times=0;
                        Serial.print("Lowest point is reached - Travel complete");
                        Serial.println();
                        flag=3;//stop motor
                      }
                     }

              //  difference=millis()-timeold;
              //  timeold = millis();
              //
              //  //Printing information after line complete
              //  Serial.print("time for one sketch = ");
              //  Serial.print(difference);
              //  Serial.println();

                Serial.print("Counter = ");
                Serial.print(counter);
                Serial.println();

                Serial.print("pulses = ");
                Serial.print(pulses);
                Serial.println();

              }

[![][1]][1]

General block diagram

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

Motor with Hall sensor, Ve is 13V, Ue is 13.5V:

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

  [1]: https://i.stack.imgur.com/bXoYO.png
  [2]: https://i.stack.imgur.com/6nNYA.png
  [3]: https://i.stack.imgur.com/Id9YP.png

I print the counter (Analog pin) and pulses (interrupt pin) with running this program code.

The Analog pin reads:

CW Voltmeasure = 574

CW Voltmeasure = 588

CW Voltmeasure = 1000

CW Voltmeasure = 999

CW Voltmeasure = 998

CW Voltmeasure = 1002

CW Voltmeasure = 1002

CW Voltmeasure = 589

CW Voltmeasure = 588

CW Voltmeasure = 590

CW Voltmeasure = 588

CW Voltmeasure = 1000......by this time motor spins 6.5 rev (based on time elapsed) but counter is only @ 3 (3 highs)

Pulses read 0.......

This is where i am at. Not able to understand Analog readings dont match the number of revs with the highs & why interupt pin reads 0......


body:
I tried modifying the voltages to interrupt pins

Now interrupt pin voltages read:
High:1.456V
Low: 1.07V

Note: The arduino is running at 12V external source.

My "pulses" counter still reads 0 for interrupts. Any idea why?


body:
All,

My Arduino is not reading interrupts across the interrupt pin:

I am getting a high of 1.456V and a low 1.07V through the interrupt pin 2... But the pulses counter still remain 0....

Any idea why?

      volatile unsigned int pulses=0; //pulse counter
      volatile int8_t steps=0;
      int timeu=0;
      int flag=2;

      void count()
      {
        pulses++;
      }

      void setup()
      {
        // initialize serial communication:
        Serial.begin(9600);
        pinMode(11,OUTPUT);
        pinMode(12,OUTPUT);
        pinMode(13,OUTPUT);
        pinMode(2,INPUT_PULLUP);
        attachInterrupt(digitalPinToInterrupt(2),count,RISING);

      }

      void stopmotor()
      {
        digitalWrite(12,LOW);
        digitalWrite(13,LOW);
        steps=0;
      }
      void motorCCW()
      {
        analogWrite(11,255);
        digitalWrite(12,HIGH);
        digitalWrite(13,LOW);
        steps=-1;
      }
      void motorCW()
      {
        analogWrite(11,255);
        digitalWrite(12,LOW);
        digitalWrite(13,HIGH);
        steps=1;
      }

      void loop()
      {

        if (timeu<=1000)//First time - Going up
        {
            sei();
            motorCW(); //moving up
            flag=8;
            timeu++;
          }
        else if (timeu==1000)
          {
              flag=10;
              stopmotor();
              cli();
              //Serial.print("Completed time cycle of 50");

          }

      if (flag==10)
      {
        Serial.print("pulses = ");
        Serial.print(pulses);
        Serial.println();

      }

      }


body:
All,

I didnt need the voltage comparator in the end, the code was running slower and wasnt picking up all the hall sensor signals that the motor was giving due to loop time. i changed the ifs to else ifs and then i was able to get a faster loop time.

Thanks all for the help.

The device is working as intended..


message:
Can I switch a pulse solenoid from the onboard 5V/3.3V power source?

I have two pulse solenoids.  One is 6V...

http://www.ebay.com.au/itm/282002733837?_trksid=p2057872.m2749.l2649&ssPageName=STRK:MEBIDX:IT

and the other is 3.6V...

http://www.ebay.com.au/itm/131989042565?_trksid=p2057872.m2749.l2649&ssPageName=STRK:MEBIDX:IT

I have a Wemos R2 Mini with an `ESP8266` chip on it, and I'm running the switching operation through a H Bridge motor shield (which handily switches the polarity of the electricity for a short time, which opens/shuts the solenoid).

I want to run this thing off a smallish battery pack that will supply 5V to the WeMos. I have three questions:

1) Can I send a 3.6V solenoid a 60ms pulse to open/shut it from a 5V power source without burning out the coil or causing any other damage?

2) Is 3.3V too low to power a 3.6V solenoid?

3) Do pulse solenoids still generate back EMF?

I don't know a lot about solenoids or electromagnetic fields so, sorry if my questions are noobish.

body:
> 1) Can I send a 3.6V solenoid a 60ms pulse to open/shut it from a 5V
> power source without burning out the coil or causing any other damage?

No. If it's 3.6V then you need 3.6V - 5V will most likely make it smoke. Use a regulator (preferably a buck one, since it is apparently 500mA) to power your H-bridge.

> 2) Is 3.3V too low to power a 3.6V solenoid?

Maybe, maybe not. It may be that 3.6V is the absolute maximum and may switch from 3V to 3.6V.

> 3) Do pulse solenoids still generate back EMF?

Normally, yes, since they are just a coil like any other inductive load. Your H-bridge should deal with that though if designed right.

To get any meaningful answers you will need a datasheet. Buying such things from eBay is never a good idea unless you have used it before and know what it is, what its specifications are, and how you use it, or they provide a link to a datasheet. Without a datasheet most questions will be answered with a "maybe".


message:
Limiting motors to a specific position using while and if loops

I am currently building a prosthetic hand using an Arduino MEGA, an Advancer Tech Myoware sensor, and 3 TB6612FNG Dual H-bridge breakouts. I have the EMG sensor sending an analog value to the Arduino and want to use that value to open or close the hand.

The problem I have is that the motors cannot turn more than 1 second without tightening too much and breaking the hand, so I want to place a limit on the while loop telling them to move that will restrict their movement under the specified conditions to one second. Also, when the analog voltage is no longer present, I need the motors to reverse their movement so the hand releases.

Here is the code I have where `move(motor #, speed, direction)` is the function to move the hand (1 = forward, 2 = backward).

    void loop(){

      int EMGv = analogRead(EMG);

      while(EMGv >= 900){
        move(0, 255, 1); //motor 1, full speed, left
        move(1, 255, 1); //motor 2, full speed, left
        move(2, 255, 1); //motor 3, full speed, left
        move(3, 255, 1); //motor 4, full speed, left
        move(4, 255, 1); //motor 5, full speed, left

      }

To reiterate. I need the motors to move while the EMG value is over 900, BUT not move more than 1 second, even if the value is 900 for 5 seconds. I then need the motors to move one second backwards when the value dips below 900.

Thanks!

body:
You can use `millis()` feature

    unsigned long starttime;

    void loop(){

      int EMGv = analogRead(EMG);
      starttime=millis();
      while(EMGv >= 900){
     if (millis()-starttime < 1000) //limit on 1000ms
     {
        move(0, 255, 1); //motor 1, full speed, left
        move(1, 255, 1); //motor 2, full speed, left
        move(2, 255, 1); //motor 3, full speed, left
        move(3, 255, 1); //motor 4, full speed, left
        move(4, 255, 1); //motor 5, full speed, left
     } else {/*turn off motor here*/}
      }


message:
MPU-6050 - angle drift

**Setup**

- Windows 7 Entreprise
- MPU-6050 : GY-521 breakout
- Arduino Nano (chinese) with CH340 FTDI driver
- Arduino IDE 1.6.12
- [Library for the gyro][1]

---

**Problem**

When I run my code, the MPU will detect the angles at a good enough accuracy, but when I leave it on the table, the MPU starts drifting. Its not anything major, yet, but on something like a rocket guidance system, these values can srew up many things.

---
**Actual questions**

- Is this a common problem?
- Why is this happening?
- What is the best way to solve it?

---

**Note**

I'll include the code if you guys really need it, but I doubt its the problem because multiple codes have had the same problem.

Please do not recommend any other gyros.

  [1]: https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050

body:
> Is this a common problem?

Yes it is. The drift is a common problem.

> Why is this happening?

The drift results, in general, from the fact that to calculate the angles it is made an integration. The errors and noises present in the inicial variable before integration (in this case angular velocity) will be "summed" over time.
For simplicity, let's say your gyro is perfect with noise free but it has a small offset , and lets considere only rotation in one axis, meaning:

    Ang_Velocity(x) = Real_Ang_Velocity(x) + offset_x

if this was the case, the sensor standing still should output only:

    Ang_Velocity(x) = 0 + offset_x
now using the integral over time results in an output of:

    Angle(x) = int[Ang_velocity(x)] = offset_x * t

For example note that using a simple 0.01 offset over axis x, causes the sensor to output 1rad angle after 100 seconds and in fact the sensor didn't move at all.

Taking this as example the sources of errors I'm aware of are:

 - **offset:** already talked
 - **scale factor:**  is the relation between input and output
 - **scale factor linearity:** sometimes the scale factor at slow speeds are not the same as speed increases.
 - **temperature:** (not 100% sure!) this changes the sensitivities of axis. Majority of digital sensores already come with an integrated temperature sensor. If not auto compensated, there will be probably information on the datasheet to guide you how to compensate for this. If your application will not take high temperature variations, it is common sense to let the sensor achieve thermal internal stability and then do a simple calibration.
 - **Random Walk:** This is probably the hardest to process. In general is assumed that the noise is a normal distribution with mean of zero and a certain variance (white noise). If that was true, the integral over time, as time increases would go to zero (because the mean is zero). However, the noise is usually not evenly distributed in the spectrum, causing the integral to not tend to zero (Brownian noise).

> way to solve it?

The first two are simple using calibration. You must do a series of tests at diferent rotation speeds to determining the non-linearities, offsets (at zero speed) and scales factors for each axis.
Then your sensor equation of the module should take acount for this facts. Usually the sensor datasheets describes the equation to be used.
Take a look at **IMU_Zero** in the repository you gave.

As for the other two, it depends on the application. Typically the temperature will be considered stable after a few working minutes. If temperature is important datasheet will probably be your best friend.

As for random walk. The most common use to take into account corrections of this is to use an accelerometer (and in some cases magnetometer) and apply a sensor fusion algorithm generally denoted as AHRS.
Some examples go as:

 - Sebastian Magdwick - [Open source IMU and AHRS algorithms][1]
 - Extended Kalman Filter
 - Direction Cosine Matrix filters
 - Complementary filters

If you really want to model the noise of the sensor to improve the result, you probably should search for Allan variance but you will need a lot of basis in stochastic processes and statistical theory

Some devices like yours already have an Motion processor built-in, that makes a similar application of (probably) one of these filters. See examples **MPU6050_DMP6.ino**

If you just want an implementation, just google for AHRS arduino. Github as a lot of examples used by other sensors that are easy to adapt. [For instance][2] and [this][3]

[More information on IMU errors](http://www.novatel.com/assets/Documents/Bulletins/APN064.pdf)

  [1]: http://x-io.co.uk/open-source-imu-and-ahrs-algorithms/
  [2]: https://github.com/sparkfun/MPU-9250_Breakout/blob/master/Libraries/Arduino/src/quaternionFilters.cpp
  [3]: https://github.com/Razor-AHRS/razor-9dof-ahrs/blob/master/Arduino/Razor_AHRS/DCM.ino


body:
The change in yaw (rotation of the x-y plane around the z-axis) is not drift or an error that needs to be nullified.
I set my MPU-6050 on the kitchen table and collected the axis outputs over a six and one half hour period.  The pitch and roll values were rock solid over the entire period.
  The Yaw values, however, constantly change at an extremely linear rate of 0.25 degrees per minute.  That's 15 degrees per hour. The planet you are on is rotating at that rate. This is not a coincidence.


message:
read AM signal only with an Arduino

Some people have managed to send simple AM signals with just a bare Arduino. An example is [here][1].
This works thanks to the fact that the PWM can reach high frequencies and, setting the divider properly, it is possible to broadcast a 1337 kHz carrier over a short distance with just a wire acting as an antenna.
I know it's not that useful, but it's really nice as an educational tool.

I was wondering if it would be possible to apply the same concept, but for the receiver. For instance simply using a pulseIn() detection on a pin connected to an antenna. Would it be possible to detect the carrier, and, maybe, even demodulate a message, eg, in morse code?

If not, would just a adding an amplifier be sufficient? Any recommendations for the amplfier and the circuit?

Thanks very much for your suggestions.

  [1]: http://mateslab.weebly.com/am-radio-broadcasting-with-arduino.html

body:
AM (*Amplitude Modulation*) varies the amplitude of the carrier based on the input signal. So, assuming you had some circuitry ([LC circuit][1]) to receive a particular carrier frequency and managed to boost the voltage so that it was in the range 0-5v then you would able to feed this to an analog input on the Arduino.

[AnalogRead][2] requires around 100uS per sample, so your max sampling rate would be 10K/s, which might **just** cut it for voice (up to 3.4Khz, sampling at least 2 * the highest freq).

However, you then need to do something with the sample value (in code) and depending on how long that 'something' takes, your *actual* sample rate will be reduced.

  [1]: https://en.wikipedia.org/wiki/LC_circuit
  [2]: https://www.arduino.cc/en/Reference/AnalogRead


body:
Generating an AM signal is child's play compared to detecting one.

To generate a signal you just need to create an oscillation and vary the amplitude, which can very crudely be done with PWM.

That's simple.

To *receive* a signal you first need to *isolate* that signal. There's a huge number of signals and noise around all the time, and you need to *tune in* to the signal that you are interested in. That's what you are doing when you twiddle the dial on a radio. You're selecting which frequency to listen to.

And to do that requires a *tuned circuit* - a kind of band-pass filter which isolates and amplifies the frequency you are interested in.

Imagine you are in a large hall filled with people. Every single person there is just standing around talking out loud - everyone is saying something different. Some are even just screaming, or whimpering in the corner. It's just a cacophony of noise. Impossible to know what is going on. That's what the air waves are like. You need some way of "tuning in" to one person's voice so you can understand what they are saying. As humans we often do that using sight, to watch a person's lips and our clever brains link the movement to the sound and help us pick out their voice. Coupled with our ability to select on the tonal qualities of a voice as well, we can pick out a single voice in the noise. That's what the tuned circuit does. It picks out one voice from the mayhem.

The Arduino can't do that. It would need to use some fairly sophisticated filtering algorithms, and it just doesn't have the power for that. Firstly you'd need to sample  the raw RF noise at a minimum of twice the frequency you are interested in (so multi-mega-samples per second), and then you'd need to do digital filtering to isolate that one frequency. From then you'd need to do more filtering to demodulate the original signal from the modulated signal.

It's all possible to do in software, but not with an Arduino. It takes a good ADC and a DSP to do all the hard work.

Easier to just build a small tuned circuit from a few passive components.


message:
error: stray '\' in program with servo

I'm doing a project for school using Arduino to make a catapult, but I have this error that I didn't have the previous week.

Can anyone see the program and search where is the error?

    #include <Servo.h> //libreria necesaria para utilizar el Servo

    Servo catac; //motor de giro continuo utilizado

    int ledPin = 13; //led conectado a agujero 13
    int button = 8; //boton conectado a agujero 8
    int estado = 0; //varaible que permite saber el estado del boton

    void setup()
    {
        pinMode(ledPin,OUTPUT);
        pinMode(button,INPUT);
        catac.attach(12); // servo unido al agujero 12
        catac.write(180); //coloca al servo en 180 grados
    }

    void loop()
    {
        estado = digitalRead(button); //la variable obtiene el estado del boton
        if(estado == LOW)
        {
            digitalWrite(ledPin,HIGH); //prende led
            catac.write(70); //servo levanta a 70 grados la catapulta
            delay(500);
            digitalWrite(ledPin,LOW); //apaga led
            catac.write(180); //servo coloca a la catapulta en posicion original
        }
    }

Error:

    cataoukta:6: error: stray '\' in program
    cataoukta:8: error: stray '\' in program
    cataoukta:9: error: stray '\' in program
    cataoukta:10: error: stray '\' in program
    cataoukta:13: error: stray '\' in program
    cataoukta:14: error: stray '\' in program
    cataoukta:15: error: stray '\' in program
    cataoukta:16: error: stray '\' in program
    cataoukta:20: error: stray '\' in program
    cataoukta:22: error: stray '\' in program
    cataoukta:23: error: stray '\' in program
    cataoukta:24: error: stray '\' in program
    cataoukta:25: error: stray '\' in program
    cataoukta:26: error: stray '\' in program
    cataoukta:9: error: expected constructor, destructor, or type conversion before 'void'
    cataoukta:6: error: expected initializer before 'u037e'
    cataoukta.ino: In function 'void loop()':
    cataoukta:20: error: 'estado' was not declared in this scope
    cataoukta:20: error: 'button' was not declared in this scope
    cataoukta:20: error: expected `;' before 'u037e'

body:
You have bad Unicode characters in your code. All your semicolons are something completely different and need replacing with *real* semicolons.

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

  [1]: https://i.stack.imgur.com/5FFMg.png


message:
Combining arduino leonardo code with water alarm code

I need to create something for a school assignment, but I'm stuck at the moment.
I have one code, which makes the Arduino Leonardo press space button on my laptop, which works.

I have another code, that turns on the LED when 2 wires are put in water.

Now I want to combine them, but I have no success.

Hope someone will help me with this.

These are the codes:

**The keyboard code leonardo:**

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

    bool eenkeergeweest = false;

    #include <Keyboard.h>

    void setup()
    {
        // make pin 2 an input and turn on the
        // pullup resistor so it goes high unless
        // connected to ground:
        pinMode(2, INPUT_PULLUP);
        // initialize control over the keyboard:
        Keyboard.begin();
    }

    void loop()
    {
        // while (digitalRead(2) == HIGH) {
        //   // do nothing until pin 2 goes low
        //   delay(500);
        //  }
        delay(1000);
        // new document:
        if (!eenkeergeweest) {
            eenkeergeweest = true;
            Keyboard.print(' ');
            delay(100);
            //Keyboard.releaseAll();
        }

        // wait for new window to open:
        delay(1000);
    }

**The code for the water LED:**

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

    int out = 12;
    int in = 4;

    int rd;

    void setup()
    {
        pinMode(out, OUTPUT);
        pinMode(in, INPUT);
    }

    void loop()
    {
        rd = digitalRead(in);
        if (rd == HIGH)
        {
            digitalWrite(out, HIGH);
            delay(100);
        }
        else
        {
            digitalWrite(out, LOW);
            delay(100);
        }
    }

body:
How do you want them to work ? Do you want the spacebar pressed when there is a high signal read (when the light goes on)?

If you want the space bar press when it goes high this might work:

    #include <Keyboard.h>

    bool eenkeergeweest = false;
    int out = 12;
    int in = 4;

    void toggleKeyPress (const char& keypress)
    {
        if (!eenkeergeweest)
     {
            eenkeergeweest = true;
            Keyboard.print(' ');
            delay(100);
     }
    }

    void setup()
    {
        pinMode(out, OUTPUT);
        pinMode(in, INPUT);

        // initialize control over the keyboard:
        Keyboard.begin();

    }

    void loop()
    {
        const int rd = digitalRead(in);
        if (rd == HIGH)
        {
      toggleKeyPress(' ');
            digitalWrite(out, HIGH);
      // wait for new window to open:
      delay(1000);
     }
        else
        {
            digitalWrite(out, LOW);
        }
    }


message:
Traffic lights using timer

My traffic light code for the Arduino doesn't run. I was wondering if anyone could point out where my issues lie. The red and green LEDs should be on for 15 seconds and the amber on for 5 seconds.

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

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <stdint-gcc.h>
    /*15 second interrupt*/
    #define INTERRUPTS 975

    /*
     * col = current colour of light.
     * 'g', 'a', 'r', 'o'
     */
    volatile uint8_t count;
    volatile char col;

    ISR(TIMER0_OVF_vect)
    {
     count++;
     if (count >= INTERRUPTS){
      if (col == 'g'){
       /*switch to amber*/
       col = 'a';
       /*reset counter*/
       count = 0;
       /*timer counter to 171 as we only need 85 clicks for 5s*/
       TCNT0 = 171;
       PORTD = 0b00000010;
      } else if(col == 'a'){
       col = 'r';
       count = 0;
       TCNT0 = 0;
       PORTD = 0b00000100;
      } else if (col == 'r'){
       col = 'o';
       counter = 0;
       TCNT0 = 171;
       PORTD = 0b00000010;
      } else if (col == 'o'){
       col = 'g';
       count = 0;
       TCNT0 = 0;
       PORTD = 0b00000001;
      } else{
       return;
      }
     } else{
      if(col == 'g' || col == 'r'){
       TCNT0 = 0;
      } else if(col == 'a' || col == 'o'){
       TCNT0 = 171;
      }
     }
     return;
    }

    int main(void)
    {
     /* normal mode */
     TCCR0A = 0b00000000;
     /* prescaler = 1024 */
     TCCR0B = 0b00000101;
     /* enable overflow interrupts */
     TIMSK0 = 0b00000001;
     TCNT0 = 0;
     sei();
     /*Initialise output*/
     DDRD = 0b11111111;
     count = 0;
     col = 'g';
     PORTD = 0b00000001;
     while (1){
        }
    }

body: As far that i understand, you set the color using the Ports directly. In case green and red you set PORTD = 0b00000010;


body:
    #define INTERRUPTS 975

    volatile uint8_t count;

    if (count >= INTERRUPTS){

`count` is an 8 bit integer, so the maximum value of it is `255`. Therefor `count` will never be bigger of equal to 975.

Use `volatile uint16_t count;` instead.

PS instead of messing with the `TCNT0` register, I'd use 2 different values of `INTERRUPTS` to change between 15 and 5 second intervals.

Something like `if( count>=975 || ( (col=='g'||col=='r') && count>=325 ) ){`


body:
If you want solution with a timer, I suggest to setup a 35 second cycle (35 = 15+15+5).
Then, you will trigger next LED when 0,15,30 seconds passed, and restart cycle at 35 seconds.

Other ways to achieve same effect are:
1. Use classic `delay()` function.

    while (true)
    {
        TurnOn(Green);
        delay(15000);
        TurnOn(Red);
        delay(15000);
        TurnOn(Amber);
        delay(5000);
    }

2. use `millis()` function


message:
Running Stepper motors (at least 2) at the same time

Is there a way to run a Stepper motor with Arduino MEGA 2560 with A4988 driver component.

I am using this https://github.com/laurb9/StepperDriver library and with this code,

    Serial.println("Starting motor ALL");
    int steps = atoi(third.c_str());
    int duration = atoi(fourth.c_str());

    BasicStepperDriver stepper1(steps, DIR, STEP, ENBL);
    stepper1.enable();
    stepper1.setMicrostep(MICROSTEPS);
    stepper1.setRPM(MAX_RPM);

    BasicStepperDriver stepper2(steps, DIR_2, STEP_2, ENBL_2);
    stepper2.enable();
    stepper2.setMicrostep(MICROSTEPS);
    stepper2.setRPM(MAX_RPM);

    int starttime = millis();
    int endtime = starttime;
    while ((endtime - starttime) <= duration) // mS
    {
         stepper1.rotate(90);
         stepper2.rotate(90);
         endtime = millis();
    }
    stepper1.disable();
    stepper2.disable();
    Serial.println("DONE");

The problem with this is that each stepper motor in this code waits for each other and not simultaneously like a DC motor. What could be done to make it work simultaneously?

body:
Try the [AccelStepper][1] library. It can control both steppers at the same time. Also provides some useful [examples][2]

AccelStepper with more than one stepper also requires the [Adafruit Motor library][3] to be installed.

  [1]: http://www.airspayce.com/mikem/arduino/AccelStepper
  [2]: http://www.airspayce.com/mikem/arduino/AccelStepper/AFMotor_MultiStepper_8pde-example.html
  [3]: https://github.com/adafruit/Adafruit-Motor-Shield-library


message:
Servo Control using Pushbutton

I was trying to build a system that when the user pushes the button, the servo rotates 45 degrees and than returns back to zero. This system is going to be duplicated as there will be two servos and pushbuttons.

Here's my code:

    #include <Servo.h>
    Servo solservo;  // create servo object to control a servo
    Servo sagservo;
    // twelve servo objects can be created on most boards

    int possol = 0;    // variable to store the servo position
    int possag = 0;
    int degsol=0;
    int degsag=0;

    int ledPin = 13; // choose the pin for the LED
    int solPin = 7;   // Pushbutton
    int sagPin = 8;     // variable for reading the pin status
    int valsag = 0;
    int valsol = 0;

    void setup() {
      solservo.attach(9);  // attaches the servo on pin 9 to the servo object
      sagservo.attach(10);
      pinMode(solPin, INPUT);
      pinMode(sagPin, INPUT);
      pinMode(ledPin, OUTPUT);

    }

    void loop() {
      digitalWrite(ledPin, HIGH);    //Arka İsik
      valsag = digitalRead(sagPin);  // read input value
      valsol = digitalRead(solPin);
    //Sag Servo

      if (valsag == HIGH) {
        sagservo.write(45);              // tell servo to go to position in variable 'pos'
        delay(100);                       // waits 15ms for the servo to reach the position
        sagservo.write(-45);

      }
    //Sol Servo
      if (valsol == HIGH){
        solservo.write(45);
        delay(15);
        solservo.write(0);
      }

    }

There'll probably be lots of small errors in this code, like unnecessary ints and such, but when I upload this program and push the button, it just rotates 45 deg, and doesn't come back. Is there a way that I can solve it?

Thanks in advance

body: Change `sagservo.write(-45);` to `sagservo.write(0);`.


message:
Motor Control Help

Here is my objective:

If the value of `EMGv` is at or above 900, start moving the motors left. The motors should continue to move left for a maximum of one second, provided `EMGv` stays at or above 900. If during this time `EMGv` goes below 900, the motors should move right for one second. Then the motors should stop. At any time after this should `EMGv` go above 900 again, the process should repeat.

In simpler terms, the project is a robotic hand, wired to an EMG circuit. When the EMG signal gets above 900 the hand should close by the motors all turning left for one second and when the signal goes below 900 the hand should open by the motors turning right for one second.

Here is my loop atm when `move(motor #, speed, direction (1 for left, 0 for right))` is the function to move the motors and `stop()` stops all motors

    void loop(){

      unsigned long starttime; //time limit for hand movement
      int EMGv = analogRead(EMG);
      starttime=millis();
      while(EMGv >= 900){
        if (millis()-starttime < 1000) //limit on 1000ms
        {
        move(0, 255, 1); //motor 1, full speed, left
        move(1, 255, 1); //motor 2, full speed, left
        move(2, 255, 1); //motor 3, full speed, left
        move(3, 255, 1); //motor 4, full speed, left
        move(4, 255, 1); //motor 5, full speed, left
        } else {
          stop();
        }
      }
    }

body:
I suspect you would do well to first write (in English) the *exact* set of rules you want it to follow -- don't worry about the code to begin with - get it clear in your head what you want the code to do.  (If this is already clear to you, then just write it :-) )

Here's what I think you might mean -- although it's not exactly what you wrote.

*If EMG is at or above 900, start moving the motors left.  The motors should continue to move left for a maximum of one second, provided EMG stays at or above 900.  If during this time EMG goes below 900, the motors should move right for one second.  Then the motors should stop.*

Once you have that, turning it into code looks well within your ability, judging by the code you've posted.  Here's my attempt - note that it'll only be correct if I have correctly stated your desired rules.  (And if I've correctly guessed how the `move` API works - I guess it starts the motor moving, that you need to cancel it to stop it moving.  Please say if this is wrong.)

I've used LEFT and RIGHT instead of 1 and *whatever*, for clarity.

    void loop(){
      // If EMG is at or above 900
      int EMGv = analogRead(EMG);
      if (EMGv >= 900)
      {
        unsigned long starttime = millis();

        // Start the motors moving left
        move(0, 255, LEFT); //motor 1, full speed, left
        ...and the other motors...

        // Continue for a maximum of one second, and while EMG stays at or above 900
        while ( (millis()-starttime < 1000) && ((EMGv = analogRead(EMG)) >= 900)) {
          // Just wait
          delay(1);
        }

        // If during this time EMG goes below one second...
        if (EMGv < 900) {
          // ...the motors should move right for one second
          move(0, 255, RIGHT); //motor 1, full speed, right
          ...and the other motors...
        }

        // Then the motors should stop.
        move(0, 0, LEFT); //motor 1, stop, left
        ...and the other motors...
      }

    // More stuff here, otherwise it will immediately go round the loop again and start moving again
    }


message:
XBee: How do I create a packet?

I am currently using a simple protocol I created to send three bytes (unit information, data, and XOR) individually over an XBee radio (3 bytes are considered a single transmission). However, this is not always reliable if a byte is dropped. For this reason I'd like to encapsulate each individual byte as a packet in a way that the Arduino could identify which byte is which and if a byte is lost then just wait for the next transmission. What I am not sure about is creating a packet. I haven't been able to find any tutorials or example code.

body:
 - The [x-ctu][1] xbee config tool has a few options worth exploring
   such as error checking. This means the xbee would do the work.

*OR using the Arduino(s)*

 - Adding a couple more bytes to you your current system with a checksum
   of the first 3 bytes would be a simple way to check for a valid
   packet.
 - You could also use a struct of values (along with a checksum).
          Bill Porter has written an Arduino Library called [Arduino Easy    Transfer][2]. The library is designed to send and receive a
   struct    along with checksum validation. This is an [overview page][3] for the library.

 - Sending and receiving structs over `Serial` is also covered [here][4]

  [1]: https://www.digi.com/products/xbee-rf-solutions/xctu-software/xctu
  [2]: https://github.com/madsci1016/Arduino-EasyTransfer
  [3]: http://www.billporter.info/2011/05/30/easytransfer-arduino-library/
  [4]: https://arduino.stackexchange.com/questions/203/sending-large-amounts-of-serial-data


body:
The biggest mistake people always make with serial communications of any form is to just send raw data over the connection. While you might just about get away with that on a 100% reliable direct serial connection over a short distance, as soon as you introduce anything with any form of uncertainty to it you are, as you have seen, doomed to failure.

So you have to come up with a reliable method of transferring data in such a way that the receiver knows that it has received valid data, and how to find valid data.

So you need to create a packet. That's not something where you just wave a magic wand and a packet is created. A packet starts it's life in your own head.

In order to reliably transfer data there are a few things you need to consider from the point of view of the receiver:

* Where is the start of my data?
* How much data is there?
* Is this data correct?

The receiver has to have some way of knowing where the start of a packet is amid the torrent of bytes it is being sent. It needs to look out for something unique, something it cannot mistake for anything else. This is called synchronisation. It is often done with a specific sequence of bytes (known as a *preamble*) that can, through various means, never appear anywhere else.

And at that point things start to get a little more complex, for now you need some way of wrestling that kind of thing into a system that can only send bytes of 0 to 255 with no way of distinguishing raw data from control information like this synchronisation sequence. And that is where the concept of *escaping* comes in. This is where you nominate certain byte values as control bytes and decide that these bytes will never appear in your data without some kind of marker to say they are data bytes. A common escape marker is 255 (used in the telnet protocol) or 27 (the ANSI ESC character) although any character can be chosen.

For instance if you choose to have a synchronisation sequence of 0xAA, 0x55, you can then decide that neither of those bytes will ever appear in your data without first being preceeded by character 0xFF. So if you happened to have that sequence in your data you would expand it out to 0xFF, 0xAA, 0xFF, 0x55.  But what if you want to send the value 0xFF, in your data? How do you handle that? Well, you also escape 0xFF as well. 0xFF, being the escape character, has no actual value in the data. It only says that the next character must be interpreted as data. So to send 0xFF you would actually send 0xFF, 0xFF. Your receiver sees the first 0xFF and thinks "ah, the next byte that arrives, whatever it is, just be data." It then gets a second 0xFF and knows it is data. (Actually this is the opposite of escaping which says the next character is a control character, but the underlying concept is the same).

If it ever sees 0xAA, 0x55 then it knows, without a shadow of a doubt, that this is the start of a packet, or random noise. And that is where the next two points above come in: Validating your packet.

If your packets are always the same size then all you need to know is how many bytes to expect, which can be hard coded into your software. If you have different sizes of data to send then you also need to tell the receiver how big the data is. This forms part of the *packet header*. A small block of meta data that preceeds the actual data that holds information about the packet. Depending on your topology that could be things like the size of the data, where the packet came from, where it is going, etc, and maybe a checksum, though some people like to put the checksum after the data since it simplifies sending.

And then there is the checksum. Possibly the most important thing next to the synchronisation. And so easy to get wrong.

Having a checksum that is too simple is not so good. It can be fooled. That is, if values get corrupted in the data with a simple checksum it is far more likely that the checksum still says it's correct than with a more complex checksum. You should read up on existing checksum algoritms, such as Cyclic Redundancy Check (CRC) and things like the checksums used in IP packets. All are good lessons on how to deal with checksums properly.

So far we have just tackled the serial equivalent of UDP - throw a packet at a receiver and hope it gets there. Doing anything more reliable becomes much more complex. If you want to know if your packet actually got there you will need your receiver to acknowledge reception, possibly including some information about the packet it received, such as a sequence number. If the transmitter never receives that acknowledgement it needs to send the packet again, which means it needs to remember what the packet is that it sent. So you need a packet buffer, or even better, a packet queue. And timeouts. And sequence numbers.

That latter is most important. A sequence number is a unique (or unique over a reasonable period of time) identifier for a packet. When a transmitter doesn't receive an acknowledgement is it because the receiver never got the packet, or that the receiver did get the packet but the acknowledgement never made it back to the transmitter? If the latter then the receiver is liable to get the same packet multiple times through retransmission. By including a sequence number the receiver can go "hang on a moment, I have seen this packet already" and it can throw it away sending a new acknowledgement in the process.

So as you can see, reliable communication isn't as simple as just sending data, or even sending data in the form of a struct. There is a whole lot more to learn and understand.

I suggest you read some of the IP networking RFCs to learn more about reliable packet transmission and reception.

Oh, and I haven't even touched on sliding window reception and such like for how to best program your receiver software...


message:
Adding fade to this RGB LED IMU

I've built an accelerometer based dice. It changes colour based on what side of the dice faces up. All is well and good, except I'd like the RGB to fade from one colour to the next instead of changes instantly.

Here's the code:

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

    include <Wire.h>
    include <Adafruit_Sensor.h>
    include <Adafruit_LSM303_U.h>
    include <Adafruit_9DOF.h>
    include <Adafruit_L3GD20_U.h>

    /* Assign a unique ID to the sensors */
    Adafruit_9DOF                 dof   = Adafruit_9DOF();
    Adafruit_LSM303_Accel_Unified accel = Adafruit_LSM303_Accel_Unified(30301);
    Adafruit_LSM303_Mag_Unified   mag   = Adafruit_LSM303_Mag_Unified(30302);

    // OUTPUT: Use digital pins 9-11, the Pulse-width Modulation (PWM) pins
    // LED's cathodes should be connected to digital GND
    int redLEDPin = 11;   // Red LED,   connected to digital pin 9
    int greenLEDPin = 10;  // Green LED, connected to digital pin 10
    int blueLEDPin = 9;  // Blue LED,  connected to digital pin 11

    // Program variables
    int red = 255;   // Variables to store the values to send to the pins
    int green = 255;
    int blue = 255;

    int lastOrientation = -1; // previous orientation

    void initSensors()
    {
      if(!accel.begin())
      {
        Serial.println(F("No LSM303 detected"));
        while(1);
      }
      if(!mag.begin())
      {
        Serial.println("No LSM303 detected");
        while(1);
      }
    }

    void setup() {

      Serial.begin(115200);
      Serial.println(F("RGB Dice... go!")); Serial.println("");

      /* Initialise the sensors */
      initSensors();

      pinMode(redLEDPin, OUTPUT);   // sets the pins as output
      pinMode(greenLEDPin, OUTPUT);
      pinMode(blueLEDPin, OUTPUT);

      int lastOrientation = -1; // previous orientation
    }

    void loop() {

      /* Get a new sensor event */
      sensors_event_t event;
      accel.getEvent(&event);

      int orientation = - 1; // dice orientation
      String orientationString; // string for printing orientation
      /*
       * orientation:
       * 1: cyan
       * 2: blue
       * 3: green
       * 4: magenta
       * 5: yellow
       * 6: red
       */

      // read accelerometer
      int x = event.acceleration.x;
      int y = event.acceleration.y;
      int z = event.acceleration.z;

      // calculate absolute values, and determin largest
      int absX = abs(x);
      int absY = abs(y);
      int absZ = abs(z);

      if ( (absZ > absX) && (absZ > absY)) {

        //base orientation Z
        if (z > 0) {
          orientationString = "1, cyan";
          orientation = 1;
          red = 255;
          green = 0;
          blue = 0;

        } else {
          orientationString = "6, red";
          orientation = 6;
          red = 0;
          green = 255;
          blue = 255;
        }

      } else if ( (absY > absX) && (absY > absZ)) {

        //base orientation Y
        if (y > 0) {
          orientationString = "2, blue";
          orientation = 2;
          red = 255;
          green = 255;
          blue = 0;

        } else {
          orientationString = "5, yellow";
          orientation = 5;
          red = 0;
          green = 0;
          blue = 255;
        }
      } else {
        //base orientation X
        if (x > 0) {
          orientationString = "4, magenta";
          orientation = 4;
          red = 0;
          green = 255;
          blue = 0;

        } else {
          orientationString = "3, green";
          orientation = 3;
          red = 255;
          green = 0;
          blue = 255;

        }
      }

      // if orientation changes, print out a description
      if (orientation != lastOrientation) {
        Serial.println(orientationString);
        lastOrientation = orientation;
      }

      analogWrite(redLEDPin, red);   // Write values to LED pins
      analogWrite(greenLEDPin, green);
      analogWrite(blueLEDPin, blue);
      delay(100);

    }

Every fading example I have adopted has broken the code so far. I guess my initial code isn't set up for it. Any ideas for a workaround?

body:
You need to be a little clearer about the time that can exist between the sensor values changing. If you fade to slowly the correct value might never be reached before the sensor changes again. Maybe that's what you want?

You can't use a `delay()`.

You need a `currentRed`, `currentGreen` and `currentBlue` so you can fade to the values of red, green and blue.

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

    unsigned long last_reading_ms;
    int red = 255;   // Variables to store the TARGET rgb target values for each pin
    int green = 255;
    int blue = 255;
    int currentRed = 0;   // Variables to store the current rgb values of the pins
    int currentGreen = 0;
    int currentBlue = 0;

    void setup()
    {
       last_reading_ms=millis();
    }

    void loop()
    {
      /* read sensor every 100ms and set red, green,blue if changed */
      if (millis()-last_reading_ms > 100)
      {
        /* Get a new sensor event */
        sensors_event_t event;
        accel.getEvent(&event);
        //the rest of your sensor reading code here

        last_reading_ms=millis()
      }

      /* if orientation changes, print out a description */
      if (orientation != lastOrientation) {
       Serial.println(orientationString);
       lastOrientation = orientation;
      }

      calculateRGBFadeTo();

      analogWrite(redLEDPin, currentRed);   // Write values to LED pins
      analogWrite(greenLEDPin, currentGreen);
      analogWrite(blueLEDPin, currentBlue);

      //*** do not use a delay or use a very small one to slow the transition ***
      //delay(100);

    }

    /* get values 1 step closer to target red, green, blue */
    void calculateRGBFadeTo()
    {
      /* fade to required rgb values */
      if (currentRed<red)
       currentRed ++;
      else if (currentRed>red)
       currentRed --;

      if (currentGreen<green)
        currentGreen ++;
      else if (currentGreen>green)
        currentGreen --;

      if (currentBlue<blue)
        currentBlue ++;
      else if (currentBlue>blue)
        currentBlue --;

    }

Notes:

The fade can be slowed down either with a small delay such as 5 ms. or by using another `millis()` variable to determine the time since the led was last set.

For example: `if (millis()-last_rgb_write_ms > 5)`

It's also possible to speed up the fade by using a larger increment. An increment of two, for example, `currentRed+=2;` instead of `currentRed++;`

Reminder, the comparison of when the target red, green, blue has been reached will be more complex with an increment greater than `1`.

An increment of `2` and a sensor read frequency of `128ms` (instead of 100) would ensure the correct RGB values are always reached. Alternatively reading the sensor every `255ms` (4-5 times per second) would also ensure the correct RGB values has been reached.

Using `millis()` and avoiding delays allows many more tasks to be performed with more accurate timings.


message:
Waking up async the Arduino while it's sleeping periodically

I´m using `LowPower.h` and `PinChangeInt.h` libraries to put my Arduino into the sleep mode every 8 seconds and then it wakes up, modifies a counter and it goes to sleep again, but also I need to wake it up when a button is pressed asynchronously.

I´ve reached to wake up the Arduino every 8 seconds using `LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF)` and, in other code, I´ve also reached to wake it up while it sleeps indefinitely with `LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF)` but I can´t combine that periodical awakening with the asynchronous awakening.

Here is my code:

    void setup(){

        Serial.begin(9600);

        //Pines declaration

        loopsToSend = setTimeToSend();  //

        //The three async buttons
        PCintPort::attachInterrupt(4, readOpinion,RISING);
        PCintPort::attachInterrupt(5, readOpinion,RISING);
        PCintPort::attachInterrupt(6, readOpinion,RISING);
    }

    void loop(){

        if(loops < loopsToSend ){

            byte opinionValue = readOpinion(); //This method must awake the Arduino ASYNC to give a value to the opinionValue var, write the result in the file and go to sleep

            if(opinionValue != 0){
                Serial.println("Button pressed!");

                //Writing result in a file
                opiniones++;
                delay(500);
            }
            //Go to sleep 8 seconds
            LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
            opinionValue = 0;
        }
        else {
            wdt_disable();

            if(opiniones > 0){
                //Send file using GSM module
            }
            else{
                loops = 0;
            }
        }
        loops++;
    }

Can anyone help me? Thanks

body:
This one works for me:

    #include <PinChangeInterrupt.h>
    #include <LowPower.h>

    // I want to know when it was interrupted by PCINT:
    volatile byte flag = 0;
    void handler() {
        flag = 1;
    }

    void setup() {
      Serial.begin(115200);
      pinMode(A0, INPUT_PULLUP);
      attachPCINT(digitalPinToPCINT(A0), handler, CHANGE);
    }

    void loop() {
      Serial.println("entering powerDown sleep mode");
      Serial.flush(); // wait for sending all data

      LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

      if (flag == 1) {
        flag = 0;
        Serial.println("Pin change interrupt");
      } else {
        Serial.println("Timeout");
      }
    }

However if you use RISING (or FALLING), it also wakes up from the sleep when pin changes back to the oposite state (and it'll be reported as Timeout).


message:
Using Arduino with Assembly on MacOS

I'm trying to use an Arduino UNO board with Assembly on MacOS, but I couldn't find any documentation about it.

How can I compile and upload Assembly files to the Arduino with MacOS?

body:
You can add source code to the sketch in the Arduino IDE. When adding a new source code file make sure the extension is uppercase `.S`

Files with `.S` extension will be compiled as Assembly.

There is an Arduino IDE for the mac but if you want to use an external editor you have many options.

The simplest is to switch on `File>Preferences>External Editor` in the Arduino IDE. This makes the IDE work in "read-only/auto-reload" mode allowing edit in a different code editor but compile and upload (without reopening the code) in the Arduino IDE.

There are also the `File>Preferences` `Verbose Compile` and `Verbose Upload` options in the Arduino IDE. These options will show you the commands used to compile, link and upload. You will see that the IDE runs other programs, outside of the IDE, such as `avrdude` and `g++`. Therefore a small script file can be created to call the same commands from a different IDE if the external editor doesn't have a facility to run external commands.

The verbose output will show where the tools and sources for build and upload are located. Normally for `Uno` (avr) they are below `[IDE Folder]\hardware\arduino`.


message:
Update Variable via Arduino to Arduino I2C

I am attempting to send a simple 1 byte value from one arduino to another using I2C with the Wire library. From reading I see that this is typically done using the event monitor supplied by the Wire library, but this has caused problems for me because the handler function may only have one argument and it must be a `void` function or else the library throws errors during compilation. So I have a couple of questions about what is or is not possible with the Wire library short of modifying the source:

1. Should the `Wire.available()` function respond to attempted transmissions if the event handler referenced above does not exist? My first idea was to simply write my own function that would be called whenever this value is not 0, but it appears that this value never changes - unless the event handler is used.

2. Can you update variables which reside outside of a function from inside of the function WITHOUT passing those variables as pointer arguments? Because recall from above that I cannot pass any arguments besides the one specified for the number of bytes received.

I cannot understand how this library could be useful for Arduino to Arduino communication if it is literally not possible to use the transmitted values anywhere other than inside of the event handler. My next step is start modifying the source to suit my needs, but I would imagine what I'm describing is a basic thing and would be shocked to find out that it's not possible without modification.

body:
> Can you update variables which reside outside of a function from inside of the function WITHOUT passing those variables as pointer arguments?

Yes, that's exactly what global variables are for. Make them `volatile` as they will be updated inside an ISR (or more exactly, a function called from an ISR).


body:
I see now what the issue was. But to answer my questions:

1. `Wire.available();` will not work if called outside of an event handler. I confirmed this while reading through the `Wire.cpp` source code and it explicitly states that the function should only be called from an event handler.

2. It is as simple as only a matter of updating global variables. I feel quite silly for not realizing that simply declaring variables outside of a function gives ANY function access to it rather than only the main function.

I see that the other answer mentions applying the `volatile` modification to the variables, but this is only necessary when the function in question is attached to an interrupt handler.