text:
Two rpm counters with interrupts
Can I use two interrupts on to count rpm square signals coming from two hall effect sensor modules (that has built in comparators to generate square signals) ?
What if two signals come together ? Will they conflict with each other ?
Will this work on attiny85 ?
I used to use two interrupt to read encoders where the two signals never conflict with each other
Thank you in advance

What maximum frequency do the square waves have? If you really cannot risk to loose any edge of the signals, you can use them as clock input for the 2 timers of the ATTiny

Thank you for your comment chrisl ...I have 40 Hz as maximum input, but actually I work with arduino programing language so I didn't get the idea of using 2 timers ...

Oh, during writing an answer, I found, that only 1 of the two timers has an counter input pin, so that will not work on the ATtiny85. I will add that do my anser.

You can use INT0 and PCINT. The hardware will handle the checking of the signal, and will set a flag. When any of these flags are set the CPU will call the ISR. If both signals happen at the same time, both flags will be set, and the CPU will call their ISRs, one after the other. You won't loose any signals, unless the ISR takes more time, than the time between signals. The only slight problem is that the ISR isn't necessarily called at the exact time of the event.

There is more than 1 option how this can be done. A frequency of 40Hz is relatively slow, so you are not limited by this.
In my comment I first suggested to use the Timers/Counters with the signal as input, but I found, that this is only possible with one of the two timers of the ATtiny. Despite that, I will add this to the answer for information (and because this can be possible on other boards with more timer input pins).

Using the PinChange interrupt and doing counting in software: Since the ATtiny85 has only 1 external interrupt, you have to use the PinChange interrupt for this. If activated, this interrupt will trigger, when ever one of the pins 0 to 5 changes it's value. You can mask away any pin in this range, so that it doesn't count. You would use 2 pins and mask the others away. In the interrupt routine you would check the state of the two pins and increment the respective counter:
volatile unsigned int counter1=0;
volatile unsigned int counter2=0;

ISR(PCINT0){
    if(digitalRead(input_pin_1)) counter1++;
    if(digitalRead(input_pin_2)) counter2++;
}

(Note the volatile declaration of the variables, because they change inside of an ISR). The counterX variables can then read in defined time intervals (for example very second) to calculate the RPM. Of course, executing code in an ISR can mean, that you miss another interrupt. During the short time period between the first interrupt and the completed execution of the ISR no other PinChange interrupt will get registered. If that is a problem is dependend on how often the pulses will be inside this small range. If that only happens very rarely you can ignore that, since it introduces only very small errors. You can even make the ISR faster by not using digitalRead(), which takes a bit to execute, but using direct Prt Manipulations. That makes the error more unlikely.
The interrupts have to be configured for this, so you need a setup code like this (this will use direct manipulation of the status registers of the ATtiny):
PCMSK = 0b000110; // Mask all pins for this interrupt,except for PCINT1 and PCINT2
GIFR &= ~(1 << PCIF); //Clear PinChange interrupt flag
GIMSK |= (1 << PCIE); //Enable PinChange interrupt

In the loop function you can use the non-blocking code style from the BlinkWithoutDelay example, to regularly calculate the RPM from the counter values;
void loop(){
    if(millis()-timestamp > INTERVAL){
        GIMSK &= ~(1 << PCIE); //Disable PinChange Interrupt, so that we don't get interrupted by ti
        unsigned int countervalue1 = counter1;
        unsigned int countervalue2 = counter2;
        counter1=0;
        counter2=0;
        IMSK |= (1 << PCIE); //Reenable PinChange interrupt
        // Do the calcuation here with countervalueX and show the result somewhere
    }
}

It is important to disable the corresponding interrupt, when you are accessing the counterX variables, because you have to prevent them from changing midway during processing. To keep this short, they are just copied to local variables and then released again.

Attention: the following suggestion doesn't work on an ATtiny85, since it only has 1 timer input pin.

Using both available Timers/Counters and the signals as clock input: If you really don't want to miss any pulses, you can utilize two Timers/Counters. Timers and Counters are the same. A counter increments a status register on every falling or rising edge (depending on the configuration) of a signal. If this signal is derivated from the chips clock, this is called a Timer. You would use it as a Counter, feeding each square wave to one Counter input pin. To actually get the RPM, you can either check the counters value (TCNT0) after defined time interval, or you can activate the overflow interrupt of both timers and measure the time between the overflows.
Since here the edge-sensing is done in hardware, no pulse can be missed. On the other side, this way needs more configuring and blocks 2 precious timers.

When working with the status registers in such a direct way, the datasheet of the ATtiny85 is a must read.

Ok I think using an Arduino pro mini will be cheap enough if I want to use the second method (the two timers method ) and it will be accurate ... What do you think if I want to add i2c or serial to the code ?

That shouldn't be a problem with the Pro mini, since it has hardware serial and hardware I2C. The ATtiny not, so the Pro mini really would be the better board.

If I use two interrupts will this conflict with arduino code (like if I have three loadcells that I need to read or write a value to a servo ) ?? .. my original post was about using an attiny85 (or atmega328 in arduino pro mini ) to send rpm values to a master arduino that will gather all values and make some dicitions ..

As I remember the servo library uses Timer1 and Timer 0 is normally used for the Arduino timing functions (delay, millis and siblings). To also use that a slave Arduino to read the rpm might be good. Or a bigger Arduino with more timers

If you can skip using interrupts, your Tiny could still do the job and not miss any pulses, as long as loop() can be executed at >40Hz, and the pulses are not be extremely short "spikes" but have a reasonable duty-cycle (or if short, you can sample faster):
// Pin data
static struct {
   uint8_t pinNum;
   bool wasHi;       // last state
   unsigned count;   // pulse count
} pinsDat[2] = {
   {input_pin_1, false, 0},
   {input_pin_2, false, 0},
};

void setup(){
   ; // your setup here
}

void loop(){
   countPulses();
   // ...
}

void countPulses(){
   for( uint8_t i = 0; i < 2; ++i){
      if( !digitalRead(pinsDat[i].pinNum) )
         isHigh1 = false;       // pin lo, just save its state
      else if( !pinsDat[i].wasHi ){
         ++pinsDat[i].count;    // pin hi; count it
         ++pinsDat[i].wasHi;    // save its state
      }
   }
}


text:
Controling L298n with interrupts
I'm working on my first arduino project, Sumo Robot, therefore i dont know much about programming yet.  We are supposed to use two IR sensors one on the front of the robot other on its back to avoid crossing the black line of the arena.
I wrote this simple code to control the motors.
But i have been  asked to use interrupts to raise the efficiency of my code.
So do you guys have an idea of how i can use interrupts with the L298n motor driver to move my dc motors forward and backward.
Here is my code
int fIR=7;
int bIR=8;
int fIR_value;
int bIR_value;
const int trigPin = 9;
const int echoPin = 11;

long duration;
int distance;

int IN1 = 4;
int IN2 = 5;
int IN3 = 6;
int IN4 = 12;

void setup() {
  Serial.begin(9600);
  pinMode(fIR,INPUT);
  pinMode(fIR,INPUT);
  pinMode(trigPin,OUTPUT);
  pinMode(echoPin,INPUT);
  pinMode(IN1,OUTPUT);
  pinMode(IN2,OUTPUT);
  pinMode(IN3,OUTPUT);
  pinMode(IN4,OUTPUT);

}

void loop() {

  fIR_value = digitalRead(fIR);
  Serial.print("Front IR:");
  Serial.print(fIR_value);
  Serial.print(" , ");

  bIR_value = digitalRead(bIR);
  Serial.print("Back IR:");
  Serial.print(bIR_value);
  Serial.print(" , ");

  digitalWrite(trigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = duration*0.034/2;
  Serial.print("Distance: ");
  Serial.println(distance);
  delay (500);

  if(distance<30&&fIR_value==HIGH&&bIR_value==LOW){
    STOP();
    delay(50);
    BACKWARD();
//    Serial.print("1");
  }
  else if(distance<30&&fIR_value==LOW&&bIR_value==HIGH){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("2");

  }
  else if(distance<30&&fIR_value==LOW&&bIR_value==LOW){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("3");

  }
    else if(distance>30&&fIR_value==LOW&&bIR_value==LOW){
    STOP();
    delay(50);
    ROTATE();
//    Serial.print("4");

  }
   else if(distance>30&&fIR_value==HIGH&&bIR_value==LOW){
    STOP();
    delay(50);
    BACKWARD();
//    Serial.print("5");

  }
   else if(distance>30&&fIR_value==LOW&&bIR_value==HIGH){
    STOP();
    delay(50);
    FORWARD();
//    Serial.print("6");

  }
}

void FORWARD(){

  digitalWrite(IN1,200);
  digitalWrite(IN2,0);
  digitalWrite(IN3,0);
  digitalWrite(IN4,200);
}
void BACKWARD(){

  digitalWrite(IN1,0);
  digitalWrite(IN2,200);
  digitalWrite(IN3,200);
  digitalWrite(IN4,0);
}
void ROTATE(){

  digitalWrite(IN1,200);
  digitalWrite(IN2,0);
  digitalWrite(IN3,200);
  digitalWrite(IN4,0);
}
void STOP(){

  digitalWrite(IN1,0);
  digitalWrite(IN2,0);
  digitalWrite(IN3,0);
  digitalWrite(IN4,0);
}

don't you think that you should use interrupts for the sensors?

if you didnt use interrupts with the sensors, then what would be the source of interrupts from the L298n?

Oh that's smart

How can I DM you.. Im new to this

learn how to use an interrupt on one pin ... use an interrupt with one sensor to light an LED

Yea I've tried that.. I tried to connect the LED with two push buttons

I will use the interrupts with the sensors and tell u the result.. Thank youuu

As jsotola already suggested in the comments, using interrupts for driving the motors does not make sense. With a L298N you simply set the outputs and then leave them alone until you think they should stop.
Instead you could use interrupts for your sensors.
Though I would argue, that using interrupts would not be really necessary, when you implement your code the right way, means non-blocking. You use a lot of delay() calls. where the Arduino does not do anything, just twiddling thumbs. Instead you could use the principle from the BlinkWithoutDelay example, that comes with the Arduino IDE, to write the code non-blocking. In that case every bit of code would only do something, if it needs to, and otherwise return fast. That would make your code run way faster. You would also need to set a lower timeout for the pulseIn() function, as it's standard timeout is 1s (ultrasonic sensors like you are using one normally can only sense up to 3m, would would correspond to 20ms max pulse duration, if I'm doing the math correctly).
If using interrupts is a mandatory part of your excercise, you can decide, where to use interrupts:

The simplest way would be for the IR sensors. You could use the attachInterrupt() function to set up an Interrupt Service Routine (ISR) for the corresponding pin. If you want the interrupt to trigger, when the IR sensors go HIGH, you can use RISING, otherwise you can use FALLING. Keep in mind, that ISRs should be as small and fast as possible. You cannot use delay() there. Normally one would only set simple (1 byte) variables in the ISR, and then react with longer actions in the main code by checking these variables. You have you set every variable, that can be changed in an ISR, as volatile:
volatile byte flag;

For the ultrasonic sensor, you have more than one way to go. I will outline 2 ways. For both of them you need to either directly manipulate the Special Function Registers of the microcontroller, or find a library, that does that for you (don't know, if such libraries exist, but you can search for them):

You could use the Pin Change Interrupt. It triggers everytime, when a pin from a full pin port (group of up to 8 pins) changes it's state. You can mask away unused pins, so that they will not influence the interrupt. In the ISR you can check the state of the pin. If it is high, the start of the pulse just happened. Save a timestamp of that moment with the micros() function. The next ISR (where the pin will be LOW) will mark the end of the pulse. Now you can calculate the time difference between the timestamp and the current micros() value. You should use a 1-byte variable as flag, to trigger the processing the the pulse duration in the main function (or, if you want to directly use the time difference variable, you need to turn of the interrupt, while you are using the variable).
If you want to show off, you could use a hardware Timer in Input Capture mode (this is the more complex, then the other possibilities). The timer is a counter, that is connected to the system clock (through a prescaler, where you can change the count frequency in a coarse way). The timer starts and when the Input Capture pin ICP1 (in case of Timer1) changes it's state, the current value of the timer will be saved in an extra register and an interrupt is fired. This timer value is like a timestamp. If you record the timestamps for the rising and the falling edge of the pulse, you can take the difference and calculate the time difference/distance from this. This part works similar to the first way above. The notes about interrupts also apply here.

See here in the https://github.com/delta-G/RobotLibs/blob/master/PingTimer.h and https://github.com/delta-G/RobotLibs/blob/master/PingTimer.cpp for an example using the interrupt capture pin method for the ultrasonic (2nd method above)

source: Stack Exchange

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

sort: votes


text:
Trouble in sensor data reading sequence
I am reading from two MPU6050 sensors using Arduino Uno but it give trouble in squence. The code is perfect and also sensors reading is done.
See image of serial monitor.

You can see the above image in which the output data of serial monitor is not lining up. It breaks the lines after some time interval. I want to expect the serial data in lining. Here is the code:
// 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 req1uired 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 mpu1(0x68);
MPU6050 mpu2(0x69); // <-- use for AD0 high

// uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
// pitch/roll angles (in degrees) calculated from the q1uaternions coming
// from the FIFO. Note this also req1uires gravity1 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

int pre_count = 0;

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

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

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

// orientation/motion vars
Quaternion q1;           // [w, x, y, z]         q1uaternion container
VectorInt16 aa1;         // [x, y, z]            accel sensor measurements
VectorInt16 aa1Real1;     // [x, y, z]            gravity1-free accel sensor measurements
VectorInt16 aa1World1;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity1;    // [x, y, z]            gravity1 vector
float euler1[3];         // [psi, theta, phi]    euler1 angle container
float ypr1[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

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

Quaternion q2;           // [w, x, y, z]         q1uaternion container
VectorInt16 aa2;         // [x, y, z]            accel sensor measurements
VectorInt16 aa1Real2;     // [x, y, z]            gravity1-free accel sensor measurements
VectorInt16 aa1World2;    // [x, y, z]            world-frame accel sensor measurements
VectorFloat gravity2;    // [x, y, z]            gravity1 vector
float euler2[3];         // [psi, theta, phi]    euler1 angle container
float ypr2[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

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

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

volatile bool mpuInterrupt1 = false;     // indicates whether MPU interrupt pin has gone high
void dmpDataReady1() {
  mpuInterrupt1 = true;
//  Serial.println("Mpu interrupt true");
}

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

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

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

  // initialize serial communication
  // (115200 chosen because it is req1uired 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 device
  Serial.println(F("Initializing I2C devices 1..."));
  mpu1.initialize();

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

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

  // verify connection
  Serial.println(F("Testing device 2 connections..."));
  Serial.println(mpu2.testConnection() ? F("MPU6050 2 connection successful") : F("MPU6050 2 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 1..."));
  devStatus1 = mpu1.dmpInitialize();

  // load and configure the DMP
  Serial.println(F("Initializing DMP 2..."));
  devStatus2 = mpu2.dmpInitialize();

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu1.setXGyroOffset(220);
  mpu1.setYGyroOffset(76);
  mpu1.setZGyroOffset(-85);
  mpu1.setZAccelOffset(1788); // 1688 factory default for my test chip

  // supply your own gyro offsets here, scaled for min sensitivity
  mpu2.setXGyroOffset(74);
  mpu2.setYGyroOffset(14);
  mpu2.setZGyroOffset(-19);
  mpu2.setZAccelOffset(253); // 1688 factory default for my test chip

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

    // enable Arduino interrupt detection
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady1, RISING);
    mpuIntStatus1 = mpu1.getIntStatus();

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

    // get expected DMP packet size for later comparison
    packetSize1 = mpu1.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 1 Initialization failed (code "));
    Serial.print(devStatus1);
    Serial.println(F(")"));
  }

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

    // enable Arduino interrupt detection
    Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
    attachInterrupt(0, dmpDataReady2, RISING);
    mpuIntStatus2 = mpu2.getIntStatus();

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

    // get expected DMP packet size for later comparison
    packetSize2 = mpu2.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 2 Initialization failed (code "));
    Serial.print(devStatus2);
    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 (!dmpReady1) return;

  // if programming failed, don't try to do anything
  if (!dmpReady2) return;

// Serial.println("code access here 1");
  // wait for MPU interrupt or extra packet(s) available
  while (!mpuInterrupt1 && fifoCount1 < packetSize1) {
    // other program behavior stuff here
    // .
    // .
    // .
    // if you are really paranoid you can freq1uently test in between other
    // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
    // while() loop to immediately process the MPU data
    // .
    // .
    // .
     break;

//    Serial.println("code access here 2");
  }

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

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt1 = false;
  mpuIntStatus1 = mpu1.getIntStatus();

  // reset interrupt flag and get INT_STATUS byte
  mpuInterrupt2 = false;
  mpuIntStatus2 = mpu2.getIntStatus();

  // get current FIFO count
  fifoCount1 = mpu1.getFIFOCount();

  // get current FIFO count
  fifoCount2 = mpu2.getFIFOCount();

  // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus1 & 0x10) || fifoCount1 == 1024) {
    // reset so we can continue cleanly
    mpu1.resetFIFO();
    Serial.println(F("FIFO overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
  } else if (mpuIntStatus1 & 0x02) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount1 < packetSize1) fifoCount1 = mpu1.getFIFOCount();

    // read a packet from FIFO
    mpu1.getFIFOBytes(fifoBuffer1, packetSize1);

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

#ifdef OUTPUT_READABLE_YAWPITCHROLL
    // display euler1 angles in degrees
    mpu1.dmpGetQuaternion(&q1, fifoBuffer1);
    mpu1.dmpGetGravity(&gravity1, &q1);
    mpu1.dmpGetYawPitchRoll(ypr1, &q1, &gravity1);
    int count = 0;
    count++;
    pre_count += count;
    Serial.print(pre_count);
    Serial.print("\t");
    Serial.print(ypr1[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr1[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr1[2] * 180 / M_PI);
    Serial.print("\t");
#endif

//    // blink LED to indicate activity
//    blinkState = !blinkState;
//    digitalWrite(LED_PIN, blinkState);
  }

   // check for overflow (this should never happen unless our code is too inefficient)
  if ((mpuIntStatus2 & 0x10) || fifoCount2 == 1024) {
    // reset so we can continue cleanly
    mpu2.resetFIFO();
    Serial.println(F("FIFO 2 overflow!"));

    // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
  } else if (mpuIntStatus2 & 0x02) {
    // wait for correct available data length, should be a VERY short wait
    while (fifoCount2 < packetSize2) fifoCount2 = mpu2.getFIFOCount();

    // read a packet from FIFO
    mpu2.getFIFOBytes(fifoBuffer2, packetSize2);

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

#ifdef OUTPUT_READABLE_YAWPITCHROLL
    // display euler1 angles in degrees
    mpu2.dmpGetQuaternion(&q2, fifoBuffer2);
    mpu2.dmpGetGravity(&gravity2, &q2);
    mpu2.dmpGetYawPitchRoll(ypr2, &q2, &gravity2);
    Serial.print("\t");
    Serial.print(ypr2[0] * 180 / M_PI);
    Serial.print("\t");
    Serial.print(ypr2[1] * 180 / M_PI);
    Serial.print("\t");
    Serial.println(ypr2[2] * 180 / M_PI);
#endif

//    // blink LED to indicate activity
//    blinkState = !blinkState;
//    digitalWrite(LED_PIN, blinkState);
  }

   // blink LED to indicate activity
    blinkState = !blinkState;
    digitalWrite(LED_PIN, blinkState);
}

What is the problem?
Thanks in advance!

I totally don't understand what you mean by "trouble in sequence". Please explain more. What are you expecting and what is actually happening?

@chrisl you can see the above image in which the output data of serial monitor is not lining up. It breaks the lines after some time interval. I want to expect the serial data in lining.

Both printing codes are inside of different if statements, which involve testing mpuIntStatus1 and mpuIntStatus2. This works good, as long as in one void loop() iteration both of these if statements are executed. But that's a timing issue and you cannot assume, that these things happen regularly and always this way. Without completely analyzing your code, the variables mpuIntStatus1/2 seem to indicate, that new data arrived. There is no reason, why this should be synchronized with the void loop() iterations.
To solve this you should rewrite your code to include all these print statements into one single if statement at the end of void loop(). In the if statements from above you can set a flag to indicate, that data arrived. This flag will be tested by the if statement at the end of loop. It is up to you to decide, how this should behave, when only data from 1 sensor arrived. You can only print the values from this sensor, or you can print both and using dummy values, that can be distinguished by humans (for example all values zero). Or you can choose to only print out values, if both sensors have given you results.

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


text:
programming relays wit millis code
Trainset info,
Turnout 1 = relay 1 - makes turnout track go left
          = relay 2 - makes turnout track go right
Turnout 2 = relay 3 - makes turnout track go left
          = relay 4 - makes turnout track go right
 Signal 1 = relay 5 - makes signal go green - train 1 starts driving
          = relay 6 - makes signal go red - train 1 stops for signal
 Signal 2 = relay 7 - makes signal go green - train 2 starts driving
          = relay 8 - makes signal go red - train 2 stops for signal

I have a arduino - uno and a 8 relay board.
I want to run a program (loop) for 1/2 hour / 1800 seconds.
Switching time should be 2 seconds (relay ON)
Can somebody help me with a millis code please.
Loop times should be:
relay 1 = (2),1250,(2),546 - total 1800 seconds
relay 2 = 620,(2),630,(2),546 - total 1800 seconds
relay 3 = 10,(2)1260,(2),526 - total 1800 seconds
relay 4 = 630,(2),640,(2),512 - total time 1800 seconds
relay 5 = 20,(2),1270,(2),505 - total time 1800 seconds
relay 6 = 600,(2),750,(2),446 - total time 1800 seconds
relay 7 = 640,(2),640,(2),516 - total time 1800 seconds
relay 8 = 1240,(2),450,(2),106 - total time 1800 seconds

Regards, Martinus van Walsum
xxxxxxxx@xxxxxxxx.com

Start at the top of your question and read outloud. Only stop to take a breath after the end of a sentence. (when a period is inserted) Did you have a difficulty saying all that without stopping? Probably. You question is very hard to read. If you want help then please make it easier for someone to figure out what you want. Did you notice that my comment uses punctuation? If we were allowed line breaks in the comments, I would also use that. It all helps with understanding. But even if you used proper punctuation, your question is still not clear. Get rid of the train speak.

@Rudy, only newlines were lost without code block

What was your specific problem with writing the code? Have you read the BlinkWithoutDelay example, which shows, how this coding style works? Have you read some of the many tutorials for this on the web? Currently I don't know, how I could help you, without having to write the whole code myself.

Btw: Putting your email address directly on a public website will only get you tons of spam.

Do you realize that Turnout 1 will be switching both left and right (at the same time) at the 1250 mark? And that Turnout 2 will be switching both left and right at the 1260 mark? And so on.

This is functional. I would do more by making a function to be called with the time and state information. It would reduce the number of if statements. But this is simple to understand. I started with Blink without delay.
I did two relays. For the others, copy and paste, then change the relay numbers and times.
/*
  Blink without Delay
  http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
*/

const int On =  1;
const int Off =  0;

// constants won't change. Used here to set a pin number:
const int ledPin =  LED_BUILTIN;// the number of the LED pin
const int relay1 =  5;
const int relay2 =  6;

// Variables will change:
int ledState = LOW;             // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0;        // will store last time LED was updated

int    secondCount = 0;

// constants won't change:
const long interval = 1000;           // interval at which to blink (milliseconds)

#define onTime  2           //relay on time

#define relay1_on1 0
#define relay1_on2 (relay1_on1+onTime+1250)

#define relay2_on1 62
#define relay2_on2 (relay2_on1+onTime+630)

void setup() {
  // set the digital pin as output:
  digitalWrite(relay1, Off);
  digitalWrite(relay2, Off);
  pinMode(ledPin, OUTPUT);
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    //------------------------------
    // Relay 1
    if (secondCount == relay1_on1) {
      digitalWrite(relay1, On);
    }
    if (secondCount == (relay1_on1 + 2)) {
      digitalWrite(relay1, Off);
    }

    if (secondCount == relay1_on2) {
      digitalWrite(relay1, On);
    }
    if (secondCount == (relay1_on2 + 2)) {
      digitalWrite(relay1, Off);
    }

    //------------------------------
    // Relay 2
    if (secondCount == relay2_on1) {
      digitalWrite(relay2, On);
    }
    if (secondCount == (relay2_on1 + 2)) {
      digitalWrite(relay2, Off);
    }

    if (secondCount == relay2_on2) {
      digitalWrite(relay2, On);
    }
    if (secondCount == (relay2_on2 + 2)) {
      digitalWrite(relay2, Off);
    }

    //------------------------------
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);

    secondCount++;
    if (secondCount == 180) {
      secondCount = 0;
    }
  }

}


text:
How to change the FFT function of the Arduino Uno for the Arduino Zero?
#define LIN_OUT 1   // Include the resources for the linear output function
#define Adafruit_ZeroFFT 256  // Sets the ZeroFFT length to 256 points
#define MERR 10     // Number of error values to store in elist[MERR]
#define PID_ON 1    // Use PID feedback or not
#define TRI_PERIOD 100 // Half-period of triangle wave in loops
#define F_BLACKMAN 0.02463994238109641755656975202572 // Osillation freq. for Blackman filter
#define ARM_MATH_CM0PLUS
#include <arm_common_tables.h>
#include <arm_math.h>
#include <Adafruit_ZeroFFT.h>
#include <SPI.h>

// Photodiode array variables

byte CLKpin = 4;    // Arduino pin delivering the clock pulses to pin 3 (CLK) of the TSL1402R
byte SIpin = 5;     // Arduino pin delivering the SI (serial-input) pulse to pin 2 of the TSL1402R
byte AOpin0 = A1;    // Arduino pin connected to pin 4 (analog output 1)of the TSL1402R
byte AOpin1 = A2;    // Arduino pin connected to pin 8 (analog output 2)of the TSL1402R

// Variables for determining the displacment from the ZeroFFT

int maxindex;       // Index of the maximum of the ZeroFFT
float maxvalue;     // For comparing the values of the ZeroFFT to find the global maximum
double kmax;        // Spatial wavenumber corresponding to the dominant fringe modulation Fourier component
float Am;           // Real part of Fourier coefficent corresponding to kmax
float Bm;           // Imag part of Fourier coefficent corresponding to kmax
float theta;        // Phase angle of Fourier transform at kmax
float preTheta = 0; // Storage for previous value of phase angle
int Nwrap = 0;      // Number of phase wraps
float displacement; // Displacement in nanometers
float predisplacement; // Storage for initial value of displacement
int w = 0;
int prevw = 0;
int wdiff = 0;

// PID Variables

unsigned long lastTime;
double Output=0;  // Output value for PID (voltage to the piezoelectric actuator (in millivolts))
double Setpoint;  // Desired value of displacement (in nm)
double kp = 0 / 1;    // 0 proportional gain for PID
double ki = 2/1;  // (1000 / (138.5)) integral gain for PID
//double ki = 2/ 1;  // (1000 / (138.5)) integral gain for PID
double kd = 0/ 100;    // 0 derivative gain for PID
double error;     // Error signal; difference between setpoint and displacement (in nm)
double preverror; // Stores previous value of error for derivative control
float esum;       // Integral of error signal over time
float D;          // Derivative of error signal
unsigned long time0 = 0; // Used in calculating the derivative term
float MSerror = 0;  // Mean squared error
float RMSerror = 0; // Root mean squared error
float elist[MERR];// Array of last MERR error values
int jerr = 0;        // index of integral error term
float runningRMSerror = 0; // RMS error calc'd from elist

float m = 0;      // extra variables for one time calculations
float pchange = 0;
float lastp = 0;
float k = 1;
int p = 1;
float M = 0;
//int switchtime = 1200; // Time (in ms) between Setpoint switches

void setup() {
  Serial.begin(9600); // Initialize serial interface to computer (i.e. serial monitor or plotter)
  INIT_PHOTO();       // Initialize the photodiode array
  READ_PHOTO();       // Read the photodiode array
  DO_ZeroFFT();           // Calculate the ZeroFFT of the photodiode array data
  FIND_PEAK_INDEX();  // Determine index of peak in ZeroFFT
  KMAX();             // Calculate spatial wavevector of the interferogram
  INIT_PHOTO();       // Maybe could be replaced by START_EXPOSURE()
  READ_PHOTO();       // Read photodiode again in preparation for next step
  PHASE_ANGLE();      // Calculate the complex phase angle of the ZeroFFT peak
  DISPLACEMENT();     // Calculate the displacement from the phase angle
  predisplacement = displacement; // Save the initial displacement corresponding to center of PZT range
  Setpoint = 0;       // Define the initial setpoint
  delay(100);         // Allow things to settle before beginning loop
  START_EXPOSURE();   // Turn on the photodiode array and begin integrating
}

void loop() {
  KMAX();                 // Calculate kmax from previous cycle's ZeroFFT
  READ_PHOTO();           // Read photodiode array
  PHASE_ANGLE();          // Calculate complex phase angle corresponding to kmax peak
  WRAPPING();            // Determine if a phase wrap occurred
  DISPLACEMENT();        // Calculate the displacement from the unwrapped phase
  DO_ZeroFFT();              // Calculate the ZeroFFT of the photodiode array data
  FIND_PEAK_INDEX();       // Determine index of peak in ZeroFFT
  //OSC_SET();             // Oscillate the setpoint up and down
  PID_LOOP();              // Perform feedback to follow the setpoint (if PID_ON is set to 1)
  //OSC_DAC();               // Send an oscillating voltage to the DAC
  //TRI_DAC();              // Send a triangular wave voltage to the DAC
  START_EXPOSURE();          // Turn on the photodiode array and begin integrating for next cycle
  SERIAL_PRINT();               // Print some outputs to the serial USB port
}

// Photodiode functions

void ClockPulse() { // For sending clock pulses during reading of photodiode
  delayMicroseconds(1);
  digitalWrite(CLKpin, HIGH);
  digitalWrite(CLKpin, LOW);
}

void INIT_PHOTO() { // Intialization of photodiode
  // Initialize two Arduino pins as digital output:
    pinMode(CLKpin, OUTPUT);
    pinMode(SIpin, OUTPUT);
  // To set up the ADC, first remove bits set by Arduino library, then choose

    for ( int i = 0; i < 14; i++ )
    {
      digitalWrite(i, LOW);
    }
  // Clock out any existing SI pulse through the ccd register:
    for (int i = 0; i < 260; i++)
    {
      ClockPulse();
    }
  // Create a new SI pulse and clock out that same SI pulse through the sensor register:
    digitalWrite(SIpin, HIGH);
    ClockPulse();
    digitalWrite(SIpin, LOW);
    for (int i = 0; i < 260; i++)
    {
      ClockPulse();
    }
}

void READ_PHOTO() { // Read the photodiode

  // Stop the ongoing integration of light quanta from each photodiode by clocking in a SI pulse
  // into the sensors register:
  digitalWrite(SIpin, HIGH);
  ClockPulse();
  digitalWrite(SIpin, LOW);

  // Next, read all 256 pixels in parallel. Store the result in the array. Each clock pulse
  // causes a new pixel to expose its value on the two outputs:
  for (int i = 0; i < 128; i++)
  {
    delayMicroseconds(20);  // We add a delay to stabilize the AO output from the sensor
    ZeroFFT_input[2 * i] = analogRead(AOpin0);        // Output of first half of photodiode array
    ZeroFFT_input[2 * i + 1] = 0;                     // Store zero in the "imaginary" part of the array
    ZeroFFT_input[2 * i + 256] = analogRead(AOpin1);  // Output of second half of photodiode array
    ZeroFFT_input[2 * i + 257] = 0;                   // Store zero in the "imaginary" part of the array
    ClockPulse();
  }

  // Next, AGAIN stop the ongoing integration of light quanta from each photodiode
  // by clocking in a SI pulse. This is necessary because during the readout operation,
  // the 18th clock pulse starts the integration of light intensity again.
  // This way we can turn on the integration when we want using the START_EXPOSURE() command.
  digitalWrite(SIpin, HIGH);
  ClockPulse();
  digitalWrite(SIpin, LOW);

  // The photodiode remains OFF after this function completes.
  // Call START_EXPOSURE() to turn on the photodiode array and begin integrating.
}

void START_EXPOSURE() {
  // The photodiode array starts integrating once 18 clock pulses have passed.
  // At that time, the photodiodes are once again active. We clock out the SI pulse through
  // the 256 bit register in order to be ready to halt the ongoing measurement at our will
  // (by clocking in a new SI pulse):
  // To be used after all calculations are finished, but
  // before the next photodiode read operation.
  for (int i = 0; i < 260; i++)
  {
    if (i == 18)
    {
      // Now the photodiodes goes active..
      // An external trigger can be placed here
    }
    ClockPulse();
  }
  // Uncomment the next line to increase the integration time.
  //delay(15);// <-- Add 15 ms integration time
}

//Calculation Functions

void DO_ZeroFFT() {  // Performs the ZeroFFT
  ZeroFFT_reorder();  // Reorders the ZeroFFT_input array to allow the ZeroFFT_run() command to be used
  ZeroFFT_run();      // This is the function that actually does the ZeroFFT
  ZeroFFT_mag_lin();  // Produces a variable ZeroFFT_lin_out that contains the absolute values of the ZeroFFT, 128 elements long.
}

void FIND_PEAK_INDEX() { // Finds the index of the major peak in the ZeroFFT
  maxvalue = 0;
  maxindex = 0;
  for (int i = 5; i < 128; i++) // Go through each element of the ZeroFFT (skip the DC peak)
  {
    if (ZeroFFT_lin_out[i] > maxvalue)
    // If the magnitude is larger than the previously seen maximum...
    {
      maxvalue = ZeroFFT_lin_out[i]; // ...store the new max...
      maxindex = i;              // ...and the index at which it occurs.
    }
  }
}

void KMAX() {
  // Calculates the spatial wavevector of the interferogram corresponding
  // to the peak in the ZeroFFT.
  kmax = 2 * PI / 256 * maxindex;
}

void PHASE_ANGLE() { // Calculates the complex phase angle of the ZeroFFT peak
  // NOTE: This function must be called BEFORE the ZeroFFT is calculated.
  Am = 0;
  Bm = 0;
  for (int i = 0; i < 256; i++) // Calculate the real and imag Fourier components
  {
    Am = Am + float ((ZeroFFT_input[2 * i]) * cos(kmax * i)); //magnitude of real part
    Bm = Bm + float ((ZeroFFT_input[2 * i]) * sin(kmax * i)); //magnitude of imaginary part
  }
  theta = atan2(Bm, Am); // Complext phase angle (in radians)
}

void WRAPPING() { // Determines if a phase wrap/unwrap occured and accounts for it
  if ((preTheta ) > (0.5 * PI) && (theta) < (-0.7 * PI)) {
    // Compare the previous theat to the current theta to see if a wrap occured.
    Nwrap = Nwrap + 1; // If so, add 1 to the number of wraps.
  }
  if ((preTheta) < (-0.7 * PI) && (theta) > (0.5 * PI)) {
    // If an unwrap occured (a phase wrap in the other direction)...
    Nwrap = Nwrap - 1; // ...then subtract 1 from the number of wraps.
  }
  preTheta = theta; // Store the current theta for the next cycle
}

void DISPLACEMENT() { // Calculate the displacement after the phase angle is determined
  m =   2 * PI * Nwrap;
  //M = theta + m;
  displacement = ((-(theta + m) * 632) * (1 / (4 * PI)) * (1 / sqrt(2))) - predisplacement;
  //displacement = ((-(theta + m) * 632) * (1 / (4 * PI)) * (0.80)) - predisplacement;
}

// Servo Functions

void PID_LOOP() { // Performs feedback signal for PID control
  error = Setpoint - displacement;

  // Store the current error signal; overwrite if necessary
  if( jerr >= MERR ){
    jerr = 0;
  }
  elist[jerr] = error;
  jerr++;

  // Calculate the running RMS error
  runningRMSerror = 0;
  for(int i=0; i<MERR; i++) {
    runningRMSerror += pow(elist[i],2);
  }
  runningRMSerror = sqrt(runningRMSerror/MERR);

  // Calculate the mean-squared and root-mean-square errors over all time
  MSerror = (k - 1) / k * MSerror + pow(error, 2) / k;
  RMSerror = sqrt(MSerror);
  k = k + 1;

  // Integral of error over all time
  esum = esum + error;

  // Derivative of error
  time0 = millis();
  D = (error - preverror) / (time0 - lastTime);

  // The feedback signal (in millivolts)
  // The minus signs are to make sure the piezo moves in the right direction
  Output = -(kp * error) -(ki * esum) -(kd * D);

  // Send the feedback to the DAC if PID_ON is 1
  /*if (PID_ON) {
    val = offset + Output;
    val = max(val, 0);    // Constrain the output voltage so that is stays in range
    val = min(val, 4096);
    DAC_TRANSFER();
  }

  // Save the current time and error for calc'ing the derivative next cycle
  lastTime = time0;
  preverror = error;*/
}

void SERIAL_PRINT(){

  Serial.print(displacement);
  Serial.print(" , ");
  Serial.println(millis());
  Serial.print(" ") ;
}

Hi every one. I tried to compile this code for the Arduino Zero which was originally written for the Arduino Uno. I got the following errors. What am I doing wrong?
Error:
/Users/RAJU/Documents/Documents/All Folders/Arduino 2017_v03_Maintable/Arduino-zero/DIS_SET_V04_Arduino-zero/DIS_SET_V04_Arduino-zero.ino: In function 'void READ_PHOTO()':
DIS_SET_V04_Arduino-zero:144: error: 'ZeroFFT_input' was not declared in this scope
     ZeroFFT_input[2 * i] = analogRead(AOpin0);        // Output of first half of photodiode array
     ^
/Users/RAJU/Documents/Documents/All Folders/Arduino 2017_v03_Maintable/Arduino-zero/DIS_SET_V04_Arduino-zero/DIS_SET_V04_Arduino-zero.ino: In function 'void DO_ZeroFFT()':
DIS_SET_V04_Arduino-zero:186: error: 'ZeroFFT_reorder' was not declared in this scope
   ZeroFFT_reorder();  // Reorders the ZeroFFT_input array to allow the ZeroFFT_run() command to be used
                   ^
DIS_SET_V04_Arduino-zero:187: error: 'ZeroFFT_run' was not declared in this scope
   ZeroFFT_run();      // This is the function that actually does the ZeroFFT
               ^
DIS_SET_V04_Arduino-zero:188: error: 'ZeroFFT_mag_lin' was not declared in this scope
   ZeroFFT_mag_lin();  // Produces a variable ZeroFFT_lin_out that contains the absolute values of the ZeroFFT, 128 elements long.
                   ^
/Users/RAJU/Documents/Documents/All Folders/Arduino 2017_v03_Maintable/Arduino-zero/DIS_SET_V04_Arduino-zero/DIS_SET_V04_Arduino-zero.ino: In function 'void FIND_PEAK_INDEX()':
DIS_SET_V04_Arduino-zero:196: error: 'ZeroFFT_lin_out' was not declared in this scope
     if (ZeroFFT_lin_out[i] > maxvalue)
         ^
/Users/RAJU/Documents/Documents/All Folders/Arduino 2017_v03_Maintable/Arduino-zero/DIS_SET_V04_Arduino-zero/DIS_SET_V04_Arduino-zero.ino: In function 'void PHASE_ANGLE()':
DIS_SET_V04_Arduino-zero:217: error: 'ZeroFFT_input' was not declared in this scope
     Am = Am + float ((ZeroFFT_input[2 * i]) * cos(kmax * i)); //magnitude of real part
                       ^
exit status 1
'ZeroFFT_input' was not declared in this scope
/Users/RAJU/Documents/Arduino/libraries/Adafruit_Zero_FFT_Library/examples/mic_tft/mic_tft.ino
/Users/RAJU/Documents/Arduino/libraries/Adafruit_Zero_FFT_Library/examples/normalized/normalized.ino

Are you sure, that this really compiled for an Arduino Uno? The used library already is for the Arduino Zero, which is totally different from the Uno. Where did you get this code from? The array ZeroFFT_input has to be defined somewhere, that the error.

That's true. Sorry for the confusion. This code compiles for the Arduino Uno if I replaced all Zero_FFT by FFT. Obviously I have to comment out the following lines of syntax to make it working for the Arduino Zero:  #define Adafruit_ZeroFFT 256
#define ARM_MATH_CM0PLUS
#include <arm_common_tables.h>
#include <arm_math.h>
#include <Adafruit_ZeroFFT.h> And I have to add one more library <FFT.h> to make it work for the Arduino Uno. If you want I will post the code which works for the Arduino Uno.

The Adafruit ZeroFFT library is not a drop in replacement for the FFT Library.
You can't easily use the same code for both.

Do you have any suggestions?

Hi Craig did you have any idea how does the FFT library work in the Arduino Zero?

No, I have never used it. I suggest reading the source code and the examples.


text:
Run encoder code simultaneously with other code in Arduino
volatile unsigned int temp, counter = 0;
int county=0;
void setup()
{

  Serial.begin(9600);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);
}

void loop()
{
  county= (counter);
  if (counter>2000){
county=0;
  }
  temp = counter;

  Serial.println(county); // Encoder step counter

}

  void ai0() {if(digitalRead(3)==LOW) {counter++;}else{counter--;}}
  void ai1() {if(digitalRead(2)==LOW) {counter--;}else{counter++;}}

Dear all, above arduino code is used for encoder as counter and code is quoted from here, the above simple code works fine. However, if I were to add some code lines below the Serial.println(county);which actually delays execution time, the counter will actually skip steps and mess up the counter which I am very dissapointed.
May I ask how to solve this issue, my thought is can arduino actually run 2 void loop simultaneously so that the counter code can be run simultaneously and not be affected by other code lines which introduces delay time that mess up the counter. Any help will be appreciated :)
volatile unsigned int temp, counter = 0;
void setup()
{

  Serial.begin(9600);   pinMode(2, INPUT_PULLUP); pinMode(3, INPUT_PULLUP); attachInterrupt(0, ai0, RISING);attachInterrupt(1, ai1, RISING);
}

void loop()
{
noInterrupts();
unsigned int county = counter;
interrupts();

  if (counter>2000){county=0;}

  Serial.println(county); // Encoder step counter

}

  void ai0() {if(digitalRead(3)==LOW) {counter++;}else{counter--;}}
  void ai1() {if(digitalRead(2)==LOW) {counter--;}else{counter++;}}

PID code
#include <PID_v1.h>
double Setpoint ;  double Input; double Output ;
volatile unsigned int temp, counterrr = 0;
int county=0;

double Kp=0, Ki=2, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, DIRECT);

void setup()
{

  Serial.begin(9600);
  Setpoint = 120;
  myPID.SetMode(AUTOMATIC);
  myPID.SetTunings(Kp, Ki, Kd);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(0, ai0, RISING);
  attachInterrupt(1, ai1, RISING);
}

void loop()
{

}

  void ai0() {
    if(digitalRead(3)==LOW) {
    counterrr++;}
    else{
      counterrr--;}

        county= (counterrr);
  Serial.println(county);
  Input = map(county, 0, 1024, 0, 1200);  // photo senor is set on analog pin 5
  myPID.Compute();
  analogWrite(9,Output);
  Serial.print(Input);
  }
  void ai1() {
    if(digitalRead(2)==LOW) {
      counterrr--;}
      else{
        counterrr++;
        }

          county= (counterrr);
  Serial.println(county);
  Input = map(county, 0, 1024, 0, 1200);  // photo senor is set on analog pin 5
  myPID.Compute();
  analogWrite(9,Output);
  Serial.print(Input);
        }

can arduino actually run 2 void loop simultaneously

No, it cannot. All AVR based Arduinos (like Uno, Nano, Mega) have only one core, thus they can only execute one thing at a time.
The typical way to go is to just not introduce delays and divide up complex things into smaller parts. That way you can rapidly switch between different parts of the code, without blocking for a longer time. For humans it will then seem as if the parts are executed simultaneously, though they are actually executed successively.
To do timed things, you would use the non-blocking coding style from the BlinkWithoutDelay example, that comes with the Arduino IDE. It uses the millis() function as a stop watch, on each loop iteration checking if enough time has passed since the last execution and executing again only if enough time passed. Much like you wouldn't bake a pizza and sitting in front of the oven until it is ready. You would regularly look at your clock to check, if enough time passed, doing other things in between.

That said, you changed the code after copying and mangled it in a weird way, so that it doesn't make much sense. Also the original code is not interrupt-safe.
The code in loop() has to do an atomic access to the volatile variable counter. This is to prevent the variable from changing in between reading it. Reading a single-byte variable (like one of type byte) is always atomic and cannot be interrupted, since this is one instruction, that will be finished before calling any interrupt service function (ISR). But unsigned int is 2 bytes big. So in rare cases the following might happen:

First byte gets read from volatile variable into the non-volatile variable
the ISR triggers and changes the volatile variable
Second byte (which is now changed) gets read into the non-volatile variable

This can lead to occasionally corrupt data.
The typical way to do this is to temporarily disable interrupts, copy the volatile variable to a local variable and then enable interrupts again. Then you can use the local variable as a snapshot of the volatile variable without corrupting the data.
noInterrupts();
unsigned int local_counter = counter;
interrupts();
if(local_counter > 2000)
    ...

For your code you should also use the same mechanism as in the original code and only send the value over serial, if it really changed. Otherwise you will spam your serial connection, which automatically will slow down your code (since you are filling up the serial buffer faster, than it is send out, so that further calls to Serial.println() will block until enough space is available in the buffer).

Hi, I have used your code above, and it does not work, problem still the same. So, I have tried the millis() function in my updated code in my post :) but it still gives the same problem. May I ask if my updated code in my post is correct :) ?

Sorry, but that is a completely different code. In the first you used interrupts for the counting (which is good), in the second one you scrapped all the interrupt code. And because of that you didn't use any of my code (that is code only needed when using interrupts to count).

"it does not work, problem still the same" - I think first you really need to understand what the code from that video does. It seems, that you don't know that. And then you can start to change it. Currently you did show, what code you added to the original and also didn't state what exactly doesn't work. You need to provide a detailed description of what you expected to happen and what actually happened, together with the code and serial output of the code in question. Otherwise we cannot help you

Hi chrisl, I have updated my code to use noInterrupts() in my post, may I know if it is correct? :)

A big thank you for your answer, by the way, very concise :)

Better, but you are still  using counter in the if statement and for assigning to temp. The point is to use counter just for assigning its value to a non-volatile variable, in this case county. In the code after that (inside loop()) you should only use county.

And if you want to reset the counter, do this inside the ISR, so in ai0() and ai1()

Let us continue this discussion in chat.


text:
How to hook up a HC-06 to Arduino Nano
So I have an arduino nano hooked up to hc-06 however every diagram of the hookup wires shows some kind of resistors (1K and 2K, rather high resistances to ignore), and I completely overlooked them. I hooked it up to my computer and it all lit up nice, however I am wondering why those resistors would be included if it still lights up. Am I slowly damaging my equipment over time?

The HC-06 itself is a 3.3V device, while the Arduino Uno/Nano is a 5V device. When using electronic devices you need to stay within their corresponding voltage limits, both in power and IO connections.
Most HC-06 boards, that you can buy, will also include a voltage regulator for the power, regulating the 5V from the Arduino down to 3.3V. If you have one of these, you can provide 5V to the HC-06 as power (otherwise you would need to use the 3V pin of the Arduino as power source for the HC-06). But these boards mostly don't have a level translation for the IO lines. And that's where the resistors come in.
The HC-06 has 2 IO lines: RX and TX.

TX will send data to the Arduino and thus be driven by the HC-06 with its 3.3V. The Arduino runs on 5V, but will still be reading 3.3V as a digital HIGH level. Thus this line is not a problem.
The RX line will be driven by the Arduino at 5V. Most devices don't like a voltage on their IO pins, that is significantly higher than their working voltage (for power). Thus you can damage the HC-06 receiving hardware, if you directly connect Arduino and HC-06.

To solve that problem you have 2 options for level translation between 3.3V and 5V:

The proper way would be to use a transistor based level translator you can get these as ready-to-use board for rather cheap (search on the big online platforms for "level translator" or "level converter"), or you can build them yourself using transistors and resistors.
Or you can use a voltage divider consisting of two resistors. When you connect them like ground -> 2kOhm resistor -> 1kOhm resistor -> TX of the Arduino, you will get the Arduinos TX signal divided down to 3.3V at the point between the two resistors. There you can connect the HC-06 RX pin. This method has drawbacks, since it also acts as parasitic low pass filter. That limits the transmission speed (baud rate). Though you can still easily drive baudrates as high as 115200 baud, which is sufficient in most cases.

So it is not a good option to just omit the resistors. It can lead to damaging the HC-06. You can choose between the above options.

Welcome! You have a good question but a little light on details. You may have damaged something, there is not enough detail to tell. You state hc-06 but no link to the module you used. They come in 3.3 and 5V models. The resistors are used to translate the voltage down, this you should never do, you are playing with tolerances and if wrong you could destroy the part. If you have a 5V Arduino and a 3.3V HC-06 Get a translator or a 5V HC-06. Lighting up only tells you there is power there. The lights (LEDs) are operational even if the micro is not even on the board. Are you slowly damaging your equipment over time? Possibly I cannot tell with what you have told us. You have not even stated it worked or not and if you even powered up.

After closer inspection it did say 3.3v I should've paid more attention. Thank you for your help :)

You are welcome. Thanks for letting us know.

@PeterDragomirov If you think one of the answers is correct, you can mark it as such. That way everyone knows, that that is the correct one and that the question was successfully answered


text:
Read 4 data types..but wait for answers
I want to ask using the Serial Monitor....for
PlayerName, Age, Money, boolean Happy....
I do not know from reading around how to make the Arduino read each value...
When I do get this to partially work, on the loop around the 2nd time it does not wait for a user entry...
#code example below...but not correct anymore??? Please assist...
void setup(){
   Serial.begin(115200);
}

void loop( ){
  Serial.print("Enter name: ");
  while(Serial.available( ) ==0);//wait
  String myName=Serial.readString();
  Serial.println(myName);

  Serial.print("age ");
  int age=Serial.parseInt();
  Serial.println(age);

  Serial.print("Money");
  double money=Serial.parseFloat();
  Serial.println(money);

  Serial.println("Happy (true/false)");
  bool blnHappy=Serial.read();
  Serial.println(blnHappy);
}

what is your specific question? ... please add a focused, answerable question to your post ... also, add your code

This may help: Reading Serial on the Arduino, by Majenko.

Here is another link that may help:  https://forum.arduino.cc/t/serial-input-basics-updated/382007

what do you mean by Arduino Processsing App?

@jsotola The Arduino IDE (at least version 1) is based on Processing.

while(Serial.available( ) ==0);  //wait
String myName=Serial.readString();

Your while loop will wait for a single character to arrive, but you want an entire string. You need to rework somewhat.
Below is an example of doing that with a non-blocking loop to handle incoming data. Also a state machine works out what to do with the incoming message.
// the possible states of the state-machine
typedef enum {  WANT_NAME, WANT_AGE, WANT_MONEY, WANT_HAPPY, RUNNING } states;

// current state-machine state
states state = WANT_NAME;

// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 50;

char name [MAX_INPUT];
int age;
long money;
bool happy;

void setup ()
  {
  Serial.begin (115200);
  Serial.println ("Enter your name ...");
  } // end of setup

// here to process incoming serial data after a terminator received
void process_data (const char * data)
  {
  switch (state)
    {
    case WANT_NAME:
      strncpy (name, data, MAX_INPUT);
      state = WANT_AGE;
      Serial.println ("Enter your age ...");
      break;
    case WANT_AGE:
      age = atoi (data);
      state = WANT_MONEY;
      Serial.println ("Enter your money ...");
      break;
    case WANT_MONEY:
      money = atol (data);
      state = WANT_HAPPY;
      Serial.println ("Are you happy? Y/N ...");
      break;
    case WANT_HAPPY:
      happy = toupper (data [0]) == 'Y';

      state = RUNNING;
      Serial.println ("Ready to play!");
      Serial.print ("Your name is ");
      Serial.println (name);
      Serial.print ("Your age is ");
      Serial.println (age);
      Serial.print ("Your money is ");
      Serial.println (money);
      Serial.print ("Your happiness is ");
      Serial.println (happy ? "yes" : "no");

      break;

    } // end of switch(state)
  }  // end of process_data

void processIncomingByte (const byte inByte)
  {
  static char input_line [MAX_INPUT];
  static unsigned int input_pos = 0;

  switch (inByte)
    {

    case '\n':   // end of text
      input_line [input_pos] = 0;  // terminating null byte

      // terminator reached! process input_line here ...
      process_data (input_line);

      // reset buffer for next time
      input_pos = 0;
      break;

    case '\r':   // discard carriage return
      break;

    default:
      // keep adding if not full ... allow for terminating null byte
      if (input_pos < (MAX_INPUT - 1))
        input_line [input_pos++] = inByte;
      break;

    }  // end of switch

  } // end of processIncomingByte

void loop()
  {
  // if serial data available, process it
  while (Serial.available () > 0)
    processIncomingByte (Serial.read ());

  // do other stuff here like testing digital input (button presses) ...

  }  // end of loop

A simpler example using more-or-less your original code is this:
void setup(){
   Serial.begin(115200);

  Serial.setTimeout(100000);   // long wait for them to enter stuff

  Serial.print("Enter name: ");
  String myName=Serial.readStringUntil('\n');
  Serial.println(myName);

  Serial.print("age ");
  int age=Serial.parseInt();
  Serial.println(age);

  Serial.print("Money");
  double money=Serial.parseFloat();
  Serial.println(money);

  Serial.println("Happy (true/false)");
  bool blnHappy=Serial.readStringUntil('\n');
  Serial.println(blnHappy);
}

void loop( ){

}

The setTimeout call means that the readString does not terminate after one second, giving you time to type in your name, I used readStringUntil so that it waits for the newline at the end of the line. It isn't perfect, but it shows the general idea.

bool blnHappy=Serial.readStringUntil('\n');  Are you sure there's an implicit conversion from String object to bool, which results eventually in false ?

I'm not sure, and when I was testing it didn't wait for me to type true or false, so I think that part isn't working. I did mention "it isn't perfect" which was alluding to that. However getting that part right is an exercise for the reader. :)

Probably all four questions should be readStringUntil and then parse the results afterwards with atoi, atol, or atof and a string comparison for "true" or "false".

@DataFiddler I don't particularly like the parseInt etc. functions with timeouts and all that, because it takes control away from you. What happens if they don't enter an integer, for example? I would rather read a string, parse that, and then put up some sort of error if they make bad input, for example not-a-number or an empty string (no input).

That's the general issue using software: if it does not do what you need and you can't accept it, you can't use it. But you should study its behavior and perhaps you can't do it better yourself. BTW : bool blnHappy=Serial.readStringUntil('\n'); is nonsense.

@DataFiddler I've already said in a couple of comments that the line in question doesn't work. Perhaps you could post an answer that perfectly answers the question in an optimal way? Posting a good solution is more helpful than vaguely saying that my answer is wrong, in an unspecified way.


text:
Arduino Uno error resp=0x27
I use the Chinese copy of board. My code is right, but when i upload to board, it print me this:
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x27
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x27
Failed uploading: uploading error: exit status 1

Do you know, what is it?

It could be a number of things that we haven't enough information to diagnose. But 'not responding' is quite likely the result of the wrong- or no port or board being selected, or failure of the connection to your computer, or failure of your operating system to recognize the board.
Editing more information into your question would help: What board & chip (is it an Uno clone?), your OS, whether your board was or wasn't recognized by the OS (Windows) or the IDE (macOS), whether you've installed a CH340 or other alternative USB driver if your board requires it (most Chinese Uno clones require some version of the CH340 driver; macOS usually has it built in; Windows usually doesn't). Do some more digging and flesh out your question a lot more - you'll be able to get much better help. And you may not even need it by then!

Ok, thank you very much!


text:
I am making a rubber band gun but i cant seem to get the button to work with my code to turn the servo?
#include <Servo.h>
const int buttonPin = 3;
int buttonState = 0;

Servo myservo;
void setup() {
    myservo.attach(2);
    pinMode(buttonPin, INPUT);
}

void loop() {
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH){ myservo.write(90); }
    else { myservo.write(155); }
    delay(1000);
}

And what exactly does not work? What do you see happending or not happending? What have you expected?

So it is supposed to move a servo when I push a button but the Servo just moves back and forth randomly.

Floating input. Show your wiring.

You may also print buttonState and check it's value in the serial monitor.

Just put your button between pin3 and GND, and use the internal pullup resistor like this:
#include <Servo.h>
const int buttonPin = 3;
int buttonState = 0;

Servo myservo;
void setup()
{
    myservo.attach(2);
    pinMode(buttonPin, INPUT_PULLUP);
}

void loop()
{
    buttonState = digitalRead(buttonPin);
    if(buttonState == LOW)
    {
      myservo.write(90);
    }
    else
    {
      myservo.write(155);
    }
    delay(1000);
}

There are two problems you should pay attention to when using the button:

Floating input: => using pull-up or pull-down resistor, see Using pull-up/ pull-down
Chattering phenomenon => Debounce See button debounce

Since the servo pulse frequency is about 50 Hz it has a clock period of about 20 ms. This is more than enough to debounce buttons, so there is no need for it.


text:
I don't know how to do the code for an rtc controlling a relay
I'm doing a project for my brother witch is an automatic watering thing,
it's all working fine but I just don't know how to repeat the code to make the relay say come on for 5min at 0900 than 5min at 1200 and also 5min at 1700.
how do I do this, I'm not very good at this so I need clear instructions or someone to write it.
pls help.
thank you, James.
here is the code I need to be repeated to meet what I need done, basically I just need the relay to trigger every 4h for 5min. its on an rtc on an Arduino UNO.
#include <DS3231.h>

int Relay = 4;

DS3231  rtc(SDA, SCL);
Time t;

const int OnHour = 19; //SET TIME TO ON RELAY (24 HOUR FORMAT)
const int OnMin = 55;
const int OffHour = 19; //SET TIME TO OFF RELAY
const int OffMin = 56;

void setup() {
  Serial.begin(115200);
  rtc.begin();
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, LOW);
}

void loop() {
  t = rtc.getTime();
  Serial.print(t.hour);
  Serial.print(" hour(s), ");
  Serial.print(t.min);
  Serial.print(" minute(s)");
  Serial.println(" ");
  delay (1000);

  if(t.hour == OnHour && t.min == OnMin){
    digitalWrite(Relay,HIGH);
    Serial.println("LIGHT ON");
    }

    else if(t.hour == OffHour && t.min == OffMin){
      digitalWrite(Relay,LOW);
      Serial.println("LIGHT OFF");
    }
}

why don't you simply add two more if blocks?

no matching function for call to 'DS3231::DS3231(const uint8_t&, const uint8_t&)
please help me out

You will most likely find nobody here, who will write the code for you, since this is not a free code writing service. But I will suggest a good way.

I just need the relay to trigger every 4h for 5min

The phrase "every x hours" screams for using the modulo operator %. Modulo gives you the rest value of an integer division. See these values:
0 % 4 = 0
1 % 4 = 1
2 % 4 = 2
3 % 4 = 3
4 % 4 = 0
5 % 4 = 1
...
7 % 4 = 3
8 % 4 = 0

You see, the modulo 4 operation gives you zero every 4 hours starting with midnight. So make an if statement based on that
if(hour % 4 == 0 && min == 0)

to switch on and
if(hour % 4 == 0 && min == 5)

to switch off. Just change your code in this way and you are done.

Thankyou, I will give it a try tomorrow and see how it goes  then let you know.

Also were do I put all the 0%4 things?

In your code you already have if statements for turning the relay on and off. And I included corresponding if statements using the modulo operator in my answer. These if statements can be used to turn the relay on and off. It is your part, to write that in your code. If something in my answer is not clear, please specify what, so that I can better explain how this works.

I understand were the statements go but I have no idea were to put the list of values, as I sayed I'm pretty dumb when it comes to this so I'm sorry if I'm being a bit stubborn. I'm young and don't have a lot of knowledge on how to write this. Your hell so far is very much appreciated.

The list of values doesn't belong in your code. I've just included it to show  how the modulo operator works

'hour' was not declared in this scope

As I said, I will not write the code for you. You have to take the if statements from my answer and change them for your case. Try to understand your old code. Then try to understand, what the principle is, that I described. Then you should be able to change your code accordingly. But you need to learn and understand. You can also do some basic tutorials with your Arduino to learn the absolute basics. And learning C is also good.


text:
Cannot convert 'String' to 'uint8_t {aka unsigned char}' in initialization
Hey all I am trying to convert a string into a uint8_t with the following code:
String data = "#255101987";
String tmp1 = data.substring(1, 3);

uint8_t first  = (String)tmp1;

I am getting the error of:

cannot convert 'String' to 'uint8_t {aka unsigned char}' in initialization

Any help would be great as I thought adding (String) in front of the varible would solve the issue but it hasn't as you can tell.

Do you want the ASCII value of the character or do you want to parse the string contents as a number?

I presume from the substring call s/he expects to find 255 in the variable.

@NickGammon is correct. I am looking for the 255 within the string and needing to convert that to the uint8_t.

uint8_t first  = atoi (tmp1.substring(1, 3).c_str ());

Or even:
String data = "#255101987";
uint8_t first  = atoi (data.substring(1, 3).c_str ());

That worked great. Thanks for the help, Nick!

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


text:
9 DoF Sensor Accelerometer Readings Inconsistent
I have the following sensor stick: https://www.sparkfun.com/products/10724
It has an accelerometer, gyroscope, and magnetometer.
I have connected it to an arduino and am reading the accelerometer values while the sensor is completely flat and the values jump all over the place:
ie
0
2
3
7
-5
12
35
-3
...
This is how I am reading them:
void Accel_Init()
{
  Wire.beginTransmission(ACCEL_ADDRESS);
  Wire.write(0x2D);  // Power register
  Wire.write(0x08);  // Measurement mode
  Wire.endTransmission();
  delay(5);
  Wire.beginTransmission(ACCEL_ADDRESS);
  Wire.write(0x31);  // Data format register
  Wire.write(0x08);  // Set to full resolution
  Wire.endTransmission();
  delay(5);

  // Because our main loop runs at 50Hz we adjust the output data rate to 50Hz (25Hz bandwidth)
  Wire.beginTransmission(ACCEL_ADDRESS);
  Wire.write(0x2C);  // Rate
  Wire.write(0x09);  // Set to 50Hz, normal operation
  Wire.endTransmission();
  delay(5);
}

// Reads x, y and z accelerometer registers
void Read_Accel()
{
  int i = 0;
  byte buff[6];

  Wire.beginTransmission(ACCEL_ADDRESS);
  Wire.write(0x32);  // Send address to read from
  Wire.endTransmission();

  Wire.beginTransmission(ACCEL_ADDRESS);
  Wire.requestFrom(ACCEL_ADDRESS, 6);  // Request 6 bytes
  while(Wire.available())  // ((Wire.available())&&(i<6))
  {
    buff[i] = Wire.read();  // Read one byte
    i++;
  }
  Wire.endTransmission();

  if (i == 6)  // All bytes received?
  {
    // No multiply by -1 for coordinate system transformation here, because of double negation:
    // We want the gravity vector, which is negated acceleration vector.
    accel[0] = (((int) buff[3]) << 8) | buff[2];  // X axis (internal sensor y axis)
    accel[1] = (((int) buff[1]) << 8) | buff[0];  // Y axis (internal sensor x axis)
    accel[2] = (((int) buff[5]) << 8) | buff[4];  // Z axis (internal sensor z axis)
  }
}

Am I doing something wrong that these values aren't the same?

What does your circuit look like? That may help...

Its just the arduino and sensor...
sda -> pin A4 && scl -> pin A5

What values do you get when you do shake it?

In 'FULL_RES' mode the number you get is amount of 4mg units.
So 1 is 4mg, 2 is 8mg, -4 = -32mg.
Also note that your current code doesn't interpret the first bit (so the 13th from the right) as the sign bit, so you'll never get negative values. (Question related to this)
PS I think it is actually more like 3.9mg.

How do I go about interpreting it as the sign bit?

Like I said, just follow the link in my answer. Basically just shift left 5 positions and then divide by 32. (accel[0] = (accel[0]<<5)/32)

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


text:
Making analog telephone calls?
How can we make the Arduino board interact with old, analog telephone, and to make phone calls?
I guess it involves connecting the board to the telephone with some specific cable (how it's called?)
In addition, I assume it will require us to use the telephone low-level dialing protocol (in order to actually interact with the phone and to send commands). Where can I read about it?
Is there a reason to concern about conversation between the digital/serial board and an analogous device?
By the way, I've read that analog telephones have relatively high voltages that can easily damage the board. I'd love to get any information about things like this, related to connecting Arduino to analog telephones, in order to know about such issues and about what to be concerned and to explore.
Thanks a lot!

Buy an external voice modem with a RS-232 connection. Connect it to a RS-232C shield. Use AT commands to dial numbers and pick up calls. Use voice AT commands to transmit or receive audio.
Never attempt to connect the telephone line directly to an Arduino since, yes, you will fry it. The voltage is all wrong in the first place, and goes even higher when the phone line rings.

Or something like this (which I did not know existed until 5 minutes ago) with proper isolation.

Connect a microcontroller to a telephone line is a rather technical task and requires knowledge concerning the operation of the line, but it is not an impossible task, although it can be dangerous, and sample some nasty shocks if you're not prepared for such work.
Initially you should build a rectifier circuit, mainly for its polarizing power circuit, since you do not know which is the antibody positive your telephone line but know that tensions are measured inversely ie, when measured with respect to ground (GND) the measures will be negative, this is because it was discovered that the poles of the batteries used to be gnawed less well when connected to the system.
A second step is you develop a small coupler to avoid connecting your circuit directly to the telephone line. For this you can use a pair of low-pass filters, which are placed at each connection point of the line after the bridge rectifier, and the downside of the bridge rectifier is connected to ground your circuit with this filter. And the plus point is connected to a PWM output of your controller.
Other important information you can not connect the PWM port directly to this filter, because the voltage levels in the telephone line are quite different, namely:

When the line rings you get a voltage exceeding 60V oscillating above 20Hz.
When the line is in standby mode it remains between 30V and 48V as your carrier and region.
When the line is busy or because your circuit or another extension you will have a voltage between 6V and 12V.
Already the audio modulation in their line occurs with peak 0,7Volts equivalent to 3dBm therefore its PWM output should give output like this.

To match the level of your line voltage with the telephonic system you can use a voltage divider which has an output of 0 to 0,7Volts ie when the door PWM pulse maximum output voltage of 5V should be 0,7Volts the divisor resistive. Another way is to use an operational amplifier having a gain reverse, thus reducing output. you can also use a optoacoplado circuit with 4n25 and thus polarize the phototransistor for such variation with the pulses in your diode.
Another important component in this circuit is a pair of diodes to be done clipping the signal, ie, as our voltage limit for audio is 0,7Volts after the filters put a couple of diodes between the positive and negative of your signal filtered in the bridge rectifier, so prevent signals above this level reaches the arduino when ouver noise on the line.
More Information: http://carlosdelfino.eti.br/WorkshopTelefoniaAutomacao/


text:
SD writing problem
I have an Arduino code for logging sensor data, time and date. Then I store all the data in the SD card and then I will send the sensor value to another node by using Lora. but I can't write the data in the SD card. Please help me to solve this problem. The code is also attached.
#include <RHReliableDatagram.h>
#include <RH_RF95.h>
#include "RTClib.h"
#include <SPI.h>
#include <SD.h>

RTC_DS1307 rtc;
File myFile;

#define node_address 12
uint8_t gateway_address = 11;
const int sensor_pin = A1;
float level;

/* Chip selection */
const int CS1 = 8;/*SD Card*/
const int CS2 = 10;/*LoRa*/

/* Configure LoRa driver */
RH_RF95 driver(10,2);
RHReliableDatagram manager(driver,node_address);

void setup () {
  pinMode(sensor_pin, INPUT);
  pinMode(CS1,OUTPUT);
  pinMode(CS2,OUTPUT);
//  SPI.begin();`
  /*--------Serial port connection setup--------*/
  Serial.begin(9600);

  /*----------RTC Initialization----------*/
  Serial.println(F("Initializing RTC...!"));
  if (! rtc.begin()) {
    Serial.println(F("Couldn't find RTC"));
  }
  if (! rtc.isrunning()) {
    Serial.println(F("RTC is NOT running!"));
//    rtc.adjust(DateTime(2019, 11, 12, 12, 32, 0)); // (Year,Month,Date,Hour,Min,Sec)
  }

  /*----------SD CARD Initialization----------*/
  digitalWrite(CS2,HIGH);
  delay(500);
  digitalWrite(CS1,LOW);
  Serial.println(F("Initializing SD card..."));
  if (!SD.begin(CS1)) {
    Serial.println(F("initialization of SD Card is failed!"));
    return;
  }
  Serial.println(F("Initialization of SD Card is done."));
  /*----------LoRa Initialization----------*/
  digitalWrite(CS1,HIGH);
  delay(500);
  digitalWrite(CS2,LOW);
  if (manager.init())
  {
    Serial.println(F("LoRa Successfully Initialised "));
  } else {
    Serial.println(F("LoRa initialization failed"));
  }
  driver.setFrequency(433.0);
  driver.setTxPower(14,false);
  Serial.println();
}

void loop () {
  DateTime now = rtc.now();
  /*----------Date----------*/
  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(',');
  /*----------Time----------*/
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();

  /*----------SD card----------*/
  digitalWrite(CS2,HIGH);
  delay(500);
  digitalWrite(CS1,LOW);
  delay(100);
  myFile = SD.open("test.txt", FILE_WRITE);
  if (myFile) {
    /*----------Saving Date----------*/
    myFile.print(now.year(), DEC);
    myFile.print('/');
    myFile.print(now.month(), DEC);
    myFile.print('/');
    myFile.print(now.day(), DEC);
    myFile.print(',');
    /*----------Saving Time----------*/
    myFile.print(now.hour(), DEC);
    myFile.print(':');
    myFile.print(now.minute(), DEC);
    myFile.print(':');
    myFile.print(now.second(), DEC);
    myFile.println(',');
    level = analogRead(sensor_pin);
    myFile.print(level);
    myFile.println();
    myFile.close();
  } else {
    Serial.println("Error opening test.txt");
  }
  delay(500);
  digitalWrite(CS1,HIGH);
  delay(500);
  digitalWrite(CS2,LOW);
  char data[RH_RF95_MAX_MESSAGE_LEN];
  sprintf(data,"$%d#%d",node_address,level);
  Serial.print("Level transferred is ");
  Serial.println(data);
  Serial.println(sizeof(data));
  if(!manager.sendtoWait((uint8_t*)data,sizeof(data),gateway_address))
  {
    Serial.println("Gateway offline");
  }
  delay(500);
}

let the library handle the CS pin

Note from the SD Library documentation: "Note that even if you don't use the hardware SS pin, it must be left as an output or the SD library won't work."  SS pin for nano is 10 as far as I know. You use the pin then as a chip select for LoRa first, Probable the RoRa lib does something with it, so the SD lib got issues with it. Perhaps you try to exchage the CS pins. I haven't found any problem reported  with changing the SS pin for the LoRa Lib. And: As Juraj said: why do you write to the CS1 and CS2 if the SD and LoRa libraries have control over it?

@PeterPaulKiefer, CS pin is output. this is the most common use of the SS pin in master mode. As CS pin for the first SPI device

The OP uses two CS pins: one for LoRa (10) and one for SD (8). Both are set to output, that's right. But, there is a note in the SD lib doc that, even if one changes the CS/SS pin, one has to set the pin 10 to output. For me this is a hint that pin 10 still influences the SD lib, even if it is not used. I don't know the kind of influence (think of the Lora sets the CS pin 10 to input until it needs it; for what reason ever). So there may be an impact the LoRa lib has to the SD Lib. It's just an idea.

@PeterPaulKiefer The "influence" is in hardware. The direction register for pin 10 defines whether the SPI peripheral operates in Master or Slave mode (INPUT = slave, OUTPUT = master). If you change pin 10 to INPUT then SPI just won't work.

@Majenko Sorry, but I never said I want to change it to INPUT. I said that pin 10 has still impact on the SD lib. As you gave the hint I'm missing, I could still imagine situations where LoRa lib has impact that let the SD lib fail. E.g. the LoRa lib acts as a slave and therefor sets pin 10 to an input. As I don't know if the LoRa lib acts that way. it's just a guess. But it could also be a misplaced cable or something else. user60840: If you add a picture of your setup and provide links to the libs you used we could check that too.

You should not manually control the SD card's CS pin.  By doing so you are confusing both the library and the SD card.
There is a special operation with SD cards in "SPI" mode that isn't part of the SPI standard as part of the initialization routine whereby the master (the Arduino) must send at least 72 clock pulses to the card with the CS pin held HIGH.
By manually setting the CS pin LOW you are breaking that.
There is no call for you to ever do anything for the CS pin other than tell the library what it is - the library does everything else for you. So remove all references to digitalWrite(CS1, ...) from your code.


text:
Calculating SpO2 using pulse sensor
I was wondering is there a way to calculate SpO2 using a pulse sensor?
I calculated BPM and stress before with pulse sensor and now I want to calculate SpO2.
Link to Pulse sensor manual

That depends on the pulse sensor. For measuring SpO2 you need a sensor with 2 different LED with different light wavelengths. What sensor do you use?

@chrisl well its a Biometric Pulse Rate or Heart Rate detecting sensor . check out the link : https://www.generationrobots.com/media/DetecteurDePoulsAmplifie/PulseSensorAmpedGettingStartedGuide.pdf

For measuring oxygen saturation (SpO2) with a pulse sensor, you need to use the fact, that hemoglobin, that carries oxygen, will reflect in different light wave lengths, as hemoglobin, which doesn't carry oxygen. But that also means, that you need to use light in at least 2 different wavelengths. Common are one red (about 660nm)(though green may also work) and infrared (about 940nm). When lighted sequentially with both LEDs, you can measure the refection of both parts and calculate the ratio between them (SpO2).
But your sensor only has 1 LED, which is green. So you cannot measure SpO2 with this sensor. You need one fitting the above description.


text:
An arduino servo radar system
I am trying to make something like roomba. Everything is going perfect. I want to have an ultrasonic sensor mounted on servo motor which rotate it from 0 deg to 180 deg & from 180 deg to 0 deg and the ultrasonic sensor will detect if there is any obstacles ahead. I want to take distance from the sensor. The servo motor rotates perfectly alone but when i tries to calculates the distance by the sensor which is mounted on it. The servo stops rotating. I have seen such type of systems in many projects like obstacles avoiding cars etc but i am unable to solve this problem. Can anybody tell me what i can do to solve this problem.
The code I am trying:
#include <Servo.h>
#define trigPin 2
#define echoPin 3
long duration;
int distanceCm;
Servo myservo;

int pos = 0;

void setup() {
myservo.attach(9);
myservo.write(0);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
Serial.begin(9600);

}

void loop()
{
  for (pos = 0; pos <= 180; pos += 1)
  {
    myservo.write(pos);
    //delay(500);
   int distance = calculate_distance();
    Serial.println(distance);
  }
  delay(100);
  for (pos = 180; pos >= 0; pos -= 1)
  {
    myservo.write(pos);
    //delay(500);
   int distance = calculate_distance();
    Serial.println(distance);
  }
  delay(100);
}

int calculate_distance()
{

digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);

duration = pulseIn(echoPin, HIGH);
distanceCm = duration*0.034/2;

return distanceCm;

}

Can it be, that it doesn't stop moving, but only moving 1 degree per second? If for whatever reason pulseIn() does not sense a HIGH pulse, it will wait for it, until the timeout has passed, which defaults to 1s. That would make the movement very very slow

change the step size to 15 degrees

Yeah, add a timeout to the pulseIn() call


text:
16*2 LCD on nodeMCU
I am getting this error while uploading a simple LCD program on NodeMCU can anyone guide me??........
esptool.py v2.8
Serial port COM9
Connecting........_____....._____....._____....._____....._____....._____.....____Traceback (most recent call last):
  File "C:\Users\HP-DeViL\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.6.3/tools/upload.py", line 65, in <module>
    esptool.main(cmdline)
  File "C:/Users/HP-DeViL/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/tools/esptool\esptool.py", line 2890, in main
    esp.connect(args.before)
  File "C:/Users/HP-DeViL/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/2.6.3/tools/esptool\esptool.py", line 483, in connect
    raise FatalError('Failed to connect to %s: %s' % (self.CHIP_NAME, last_error))
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header
esptool.FatalError: Failed to connect to ESP8266: Timed out waiting for packet header

how is the LCD wired to the NodeMCU?

without i2c connector..... LiquidCrystal lcd(D1, D0, D5, D6, D7, D8); // Creates an LC object. Parameters: (rs, enable, d4, d5, d6, d7)

use some other pin instead of D8. it is io 15 a boot config pin and must be LOW at boot. or try to swap it to other pin of the LCD

Maybe just disconnect the NodeMCU from the display before flashing the software.

I have seen this behavior on esp chips as well.  This happens when you've uploaded a program that utilizes the processor very heavily or a blank program.  I've gotten it to upload by unplugging and re-plugging, trying to time it correct so that it's just booting up while the programming begins.  Just keep trying this and eventually it should get through.


text:
What is wrong with my code? (HC-SR04 using 433 mhz module);
I asked a question about this last time but I still couldn't make it work but it somehow gave me an overview about my project. Now I've created an another project that is similar to the last one, the only different thing is that I used a VirtualWire library. So I connected an HC-SR04 to an arduino board(BOARD1) with a transmitter; and a receiver to another board(BOARD2). I Followed a code in the internet similar to my project but he has an lcd display but I just want to make my sensor readings displayed in my Serial monitor what should I do?
HERE IS THE CODE FOR THE TRANSMITTER
#include <VirtualWire.h>
const int trig= 9;
const int echo= A1;

float sensorval;
float distance;
char msg[6];

void setup() {
  vw_set_tx_pin(12);
  vw_setup(2000);
  pinMode(trig,OUTPUT);
  pinMode(echo,INPUT);
  Serial.begin(9600);

}

void loop() {
  digitalWrite(trig,LOW);
   delayMicroseconds(10);
   digitalWrite(trig,HIGH);
   delayMicroseconds(10);
   digitalWrite(trig,LOW);
   delayMicroseconds(10);
   sensorval=pulseIn(echo,HIGH);

   distance = (sensorval*.0343)/2;

   Serial.print("Distance: ");
   Serial.println(distance);
   dtostrf(distance, 6,2,msg);
   vw_send((uint8_t *)msg, strlen(msg));
   vw_wait_tx();
   delay(500);

}

AND HERE IS THE CODE FOR THE RECEIVER
#include<VirtualWire.h>
#include <Wire.h>

int i;
void setup() {
  vw_set_rx_pin(12);
  vw_setup(2000);
  vw_rx_start();

}

void loop() {
  uint8_t buf[VW_MAX_MESSAGE_LEN];
  uint8_t buflen = VW_MAX_MESSAGE_LEN;

  if (vw_get_message(buf, &buflen)){
    Serial.print("distance is: ");
   Serial.print((char *)buf);
      Serial.print(buf[i]);
    }

  }

What is your actual problem? You could usually simply serial.print()/read() "into/from" those radio modules...