Fixing FIFO Overflow on Arduino - arduino

I'm multiplexing 3 IMU-6050 using a MUX4051. This is the original code:
#include "Wire.h"
const int MPU=0x68; // I2C address of the MPU-6050
int16_t AcX,AcY,AcZ,Tmp,GyX,GyY,GyZ;
int Acc_ctrl_1 = 9;
int Acc_ctrl_2 = 10;
int Acc_ctrl_3 = 11;
int chip_enable1 = 5;
void setup() {
Wire.begin(); // wake up I2C bus
// set I/O pins to outputs
Wire.beginTransmission(MPU);
Wire.write(0x6B); // PWR_MGMT_1 register
Wire.write(0); // set to zero (wakes up the MPU-6050)
Wire.endTransmission(true);
Serial.begin(115200);
pinMode(Acc_ctrl_1, OUTPUT); //S0
pinMode(Acc_ctrl_2, OUTPUT); //S1
pinMode(Acc_ctrl_3, OUTPUT); //S2 address lines
pinMode(chip_enable1, OUTPUT);
//S0=1, S1=2 and S2=4 so Y0= S0=0,S1=0,S2=0, Y4=S0=0,S1=0,S2=1
}
void loop() {
//Enable the MUX Chip 1 - Active Low
digitalWrite(chip_enable1, LOW);
// control signal for First Accelerometer
Serial.println("IMU 1");
digitalWrite(Acc_ctrl_1, LOW);
digitalWrite(Acc_ctrl_2, LOW);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
// control signal for SECOND Accelerometer
Serial.println("IMU 2");
digitalWrite(Acc_ctrl_1, HIGH);
digitalWrite(Acc_ctrl_2, LOW);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
// control signal for THIRD Accelerometer
Serial.println("IMU 3");
digitalWrite(Acc_ctrl_1, LOW);
digitalWrite(Acc_ctrl_2, HIGH);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
}
void readAccele()
{
Wire.beginTransmission(MPU);// I2C address code thanks to John Boxall
Wire.write(0x3B); // starting with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU,14,true); // request a total of 14 registers
AcX=Wire.read()<<8|Wire.read(); // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
AcY=Wire.read()<<8|Wire.read(); // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
AcZ=Wire.read()<<8|Wire.read(); // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
Tmp=Wire.read()<<8|Wire.read(); // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
GyX=Wire.read()<<8|Wire.read(); // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
GyY=Wire.read()<<8|Wire.read(); // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
GyZ=Wire.read()<<8|Wire.read(); // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
Serial.print("AcX = "); Serial.print(AcX);
Serial.print(" | AcY = "); Serial.print(AcY);
Serial.print(" | AcZ = "); Serial.print(AcZ);
Serial.print(" | Tmp = "); Serial.print(Tmp/340.00+36.53); //equation for temperature in degrees C from datasheet
Serial.print(" | GyX = "); Serial.print(GyX);
Serial.print(" | GyY = "); Serial.print(GyY);
Serial.print(" | GyZ = "); Serial.println(GyZ);
delay(5);
}
I implemented it into the Jeff Rowberg example code:
// I2C device class (I2Cdev) demonstration Arduino sketch for MPU6050 class using DMP (MotionApps v2.0)
// 6/21/2012 by Jeff Rowberg <jeff#rowberg.net>
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint8_t mpuIntStatus; // holds actual interrupt status byte from MPU
bool dmpReady = false; // set true if DMP init was successful
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64];
// I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
//#include "MPU6050.h" // not necessary if using MotionApps include file
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
// class default I2C address is 0x68
// specific I2C addresses may be passed as a parameter here
// AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
MPU6050 mpu;
// uncomment "OUTPUT_READABLE_QUATERNION" if you want to see the actual
// quaternion components in a [w, x, y, z] format (not best for parsing
// on a remote host such as Processing or something though)
//#define OUTPUT_READABLE_QUATERNION
// uncomment "OUTPUT_READABLE_EULER" if you want to see Euler angles
// (in degrees) calculated from the quaternions coming from the FIFO.
// Note that Euler angles suffer from gimbal lock (for more info, see
// http://en.wikipedia.org/wiki/Gimbal_lock)
#define OUTPUT_READABLE_EULER
// uncomment "OUTPUT_READABLE_WORLDACCEL" if you want to see acceleration
// components with gravity removed and adjusted for the world frame of
// reference (yaw is relative to initial orientation, since no magnetometer
// is present in this case). Could be quite handy in some cases.
#define OUTPUT_READABLE_WORLDACCEL
int Acc_ctrl_1 = 9;
int Acc_ctrl_2 = 10;
int Acc_ctrl_3 = 11;
int chip_enable1 = 5;
int chip_enable2 = 6;
#define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
bool blinkState = false;
// MPU control/status vars
//uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorInt16 aa; // [x, y, z] accel sensor measurements
VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements
VectorInt16 aaWorld; // [x, y, z] world-frame accel sensor measurements
VectorFloat gravity; // [x, y, z] gravity vector
float euler[3]; // [psi, theta, phi] Euler angle container
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
// packet structure for InvenSense teapot demo
uint8_t teapotPacket[14] = { '$', 0x02, 0,0, 0,0, 0,0, 0,0, 0x00, 0x00, '\r', '\n' };
// ================================================================
// === INTERRUPT DETECTION ROUTINE ===
// ================================================================
volatile bool mpuInterrupt = false; // indicates whether MPU interrupt pin has gone high
void dmpDataReady() {
mpuInterrupt = true;
}
// ================================================================
// === INITIAL SETUP ===
// ================================================================
void setup() {
pinMode(Acc_ctrl_1, OUTPUT); //S0
pinMode(Acc_ctrl_2, OUTPUT); //S1
pinMode(Acc_ctrl_3, OUTPUT); //S2 address lines
pinMode(chip_enable1, OUTPUT);
// 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 required for Teapot Demo output, but it's
// really up to you depending on your project)
Serial.begin(115200);
while (!Serial); // wait for Leonardo enumeration, others continue immediately
// initialize device
Serial.println(F("Initializing I2C devices..."));
mpu.initialize();
// verify connection
Serial.println(F("Testing device connections..."));
Serial.println(mpu.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
// wait for ready
Serial.println(F("\nSend any character to begin DMP programming and demo: "));
while (Serial.available() && Serial.read()); // empty buffer
while (!Serial.available()); // wait for data
while (Serial.available() && Serial.read()); // empty buffer again
// load and configure the DMP
Serial.println(F("Initializing DMP..."));
devStatus = mpu.dmpInitialize();
// supply your own gyro offsets here, scaled for min sensitivity
mpu.setXGyroOffset(220);
mpu.setYGyroOffset(76);
mpu.setZGyroOffset(-85);
mpu.setZAccelOffset(1788); // 1688 factory default for my test chip
// make sure it worked (returns 0 if so)
if (devStatus == 0) {
// turn on the DMP, now that it's ready
Serial.println(F("Enabling DMP..."));
mpu.setDMPEnabled(true);
// enable Arduino interrupt detection
Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
attachInterrupt(0, dmpDataReady, RISING);
mpuIntStatus = mpu.getIntStatus();
// set our DMP Ready flag so the main loop() function knows it's okay to use it
Serial.println(F("DMP ready! Waiting for first interrupt..."));
dmpReady = true;
// get expected DMP packet size for later comparison
packetSize = mpu.dmpGetFIFOPacketSize();
} else {
// ERROR!
// 1 = initial memory load failed
// 2 = DMP configuration updates failed
// (if it's going to break, usually the code will be 1)
Serial.print(F("DMP Initialization failed (code "));
Serial.print(devStatus);
Serial.println(F(")"));
}
// configure LED for output
pinMode(LED_PIN, OUTPUT);
}
// ================================================================
// === MAIN PROGRAM LOOP ===
// ================================================================
void loop() {
//Enable the MUX Chip 1 - Active Low
digitalWrite(chip_enable1, LOW);
// control signal for First Accelerometer
Serial.println("IMU 1");
digitalWrite(Acc_ctrl_1, LOW);
digitalWrite(Acc_ctrl_2, LOW);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
// control signal for SECOND Accelerometer
Serial.println("IMU 2");
digitalWrite(Acc_ctrl_1, HIGH);
digitalWrite(Acc_ctrl_2, LOW);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
// control signal for THIRD Accelerometer
Serial.println("IMU 3");
digitalWrite(Acc_ctrl_1, LOW);
digitalWrite(Acc_ctrl_2, HIGH);
digitalWrite(Acc_ctrl_3, LOW);
readAccele();
delay(500);
}
void readAccele(){
// if programming failed, don't try to do anything
if (!dmpReady) return;
// wait for MPU interrupt or extra packet(s) available
while (!mpuInterrupt && fifoCount < packetSize) {
// other program behavior stuff here
}
// reset interrupt flag and get INT_STATUS byte
mpuInterrupt = false;
mpuIntStatus = mpu.getIntStatus();
// get current FIFO count
fifoCount = mpu.getFIFOCount();
// check for overflow (this should never happen unless our code is too inefficient)
if ((mpuIntStatus & 0x10) || fifoCount == 1024) {
// reset so we can continue cleanly
mpu.resetFIFO();
Serial.println(F("FIFO overflow!"));
// otherwise, check for DMP data ready interrupt (this should happen frequently)
} else if (mpuIntStatus & 0x02) {
// wait for correct available data length, should be a VERY short wait
while (fifoCount < packetSize) fifoCount = mpu.getFIFOCount();
// read a packet from FIFO
mpu.getFIFOBytes(fifoBuffer, packetSize);
// track FIFO count here in case there is > 1 packet available
// (this lets us immediately read more without waiting for an interrupt)
fifoCount -= packetSize;
#ifdef OUTPUT_READABLE_QUATERNION
// display quaternion values in easy matrix form: w x y z
mpu.dmpGetQuaternion(&q, fifoBuffer);
Serial.print("quat\t");
Serial.print(q.w);
Serial.print("\t");
Serial.print(q.x);
Serial.print("\t");
Serial.print(q.y);
Serial.print("\t");
Serial.println(q.z);
#endif
#ifdef OUTPUT_READABLE_EULER
// display Euler angles in degrees
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetEuler(euler, &q);
Serial.print("euler\t");
Serial.print(euler[0] * 180/M_PI);
Serial.print("\t");
Serial.print(euler[1] * 180/M_PI);
Serial.print("\t");
Serial.println(euler[2] * 180/M_PI);
#endif
#ifdef OUTPUT_READABLE_WORLDACCEL
// display initial world-frame acceleration, adjusted to remove gravity
// and rotated based on known orientation from quaternion
mpu.dmpGetQuaternion(&q, fifoBuffer);
mpu.dmpGetAccel(&aa, fifoBuffer);
mpu.dmpGetGravity(&gravity, &q);
mpu.dmpGetLinearAccel(&aaReal, &aa, &gravity);
mpu.dmpGetLinearAccelInWorld(&aaWorld, &aaReal, &q);
Serial.print("aworld\t");
Serial.print(aaWorld.x);
Serial.print("\t");
Serial.print(aaWorld.y);
Serial.print("\t");
Serial.println(aaWorld.z);
#endif
;
}
}
But this is what the serial prints, FIFO Overflow.. I tried to fix it but couldn't. I can't upload an image so Ill copy and paste the serial output here as code...
Send any character to begin DMP programming and demo:
Initializing DMP...
Enabling DMP...
Enabling interrupt detection (Arduino external interrupt 0)...
DMP ready! Waiting for first interrupt...
IMU 1
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1
FIFO overflow!
IMU 2
IMU 3
IMU 1

I have been working on a stable library to get all the useful information using the MPU6050_6Axis_MotionApps20 provided by I2Cdev package. I don't know if it is useful for you, but I upload it for everyone having problems dealing with it:
GYRO.h:
#ifndef GYRO
#define GYRO
#include "Arduino.h"
#include "I2Cdev.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"
#define INTERRUPT_PIN 2 //24
#define CALIBRATION_LOOPS 500
//Error codes
#define EC_NO_ERROR 0
#define EC_DMP_MEMORY_WRITING_FAILED 1
#define EC_DMP_CONFIG_WRITING_FAILED 2
#define EC_NO_CONNECTION 3
//Offsets, put your own offsets here
#define GYRO_GX_OFFSET 93
#define GYRO_GY_OFFSET 0
#define GYRO_GZ_OFFSET 7
#define GYRO_AX_OFFSET -2550
#define GYRO_AY_OFFSET 1978
#define GYRO_AZ_OFFSET 499
class GYRO{
public:
GYRO(void);
uint8_t begin(void);
void update(void);
//All are made following the arrows with the right hand rule
inline VectorFloat getGyroscope(){return gyroscope; }
//All are made following the arrows
inline VectorDouble getAccelerometer(){return accelerometer; }
//A positive 1, indicates that the gravity is going in the oppsite way of the arrow drawed on the sensor
inline VectorFloat getGravity(){return gravity; }
//Returns the temperature in ºC
inline float getTemperature(){return temperature; }
//The time that has passed for calculating the speed with the acceleration
inline unsigned long getMicrosSpent(){return microsSpent; }
inline bool isGyroscopeUpdated(){return gyroscopeUpdated; }
private:
//Gyroscope
MPU6050 gyro; //Gyroscope configured with pin ADO-LOW
//Gyroscope readings
// MPU control/status vars
uint8_t gyroIntStatus; // holds actual interrupt status byte from MPU
uint8_t devStatus; // return status after each device operation (0 = success, !0 = error)
uint16_t packetSize; // expected DMP packet size (default is 42 bytes)
uint16_t fifoCount; // count of all bytes currently in FIFO
uint8_t fifoBuffer[64]; // FIFO storage buffer
// orientation/motion vars
Quaternion q; // [w, x, y, z] quaternion container
VectorFloat gravity; // [x, y, z] gravity vector
float ypr[3]; // [yaw, pitch, roll] yaw/pitch/roll container and gravity vector
VectorFloat gyroscope; // [x, y, z] gyroscope vector
VectorInt16 rawAccelerometer; // [x, y, z] raw acceleromer
VectorDouble accelerometer; // [x, y, z] accelerometer in m/s2
float temperature; // temperature in ºC
unsigned long lastMicros;
unsigned long actualMicros;
unsigned long microsSpent;
bool gyroscopeUpdated;
int loops_before_calibration;
};
#endif
GYRO.cpp:
#include "GYRO.h"
#include "Arduino.h"
#include "MPU6050_6Axis_MotionApps20.h"
#include "Wire.h"
volatile bool interrupt = false;
void dmpDataReady(void) {
interrupt = true;
}
GYRO::GYRO(void){
gyro = MPU6050(0x68); //Change to 0x69 if the AD0 pin of your MPU6050 is HIGH
}
uint8_t GYRO::begin(void){
Wire.begin();
Wire.setClock(400000);
uint8_t errorCode;
//Gyro initialization
gyro.initialize();
pinMode(INTERRUPT_PIN, INPUT);
if(gyro.testConnection()){
Serial.println(F("\nSend any character to begin the calibration and initialization of the gyro: "));
while (Serial.available() && Serial.read());
while (!Serial.available());
while (Serial.available() && Serial.read());
devStatus = gyro.dmpInitialize();
gyro.setXGyroOffset(GYRO_GX_OFFSET);
gyro.setYGyroOffset(GYRO_GY_OFFSET);
gyro.setZGyroOffset(GYRO_GZ_OFFSET);
gyro.setXAccelOffset(GYRO_AX_OFFSET);
gyro.setYAccelOffset(GYRO_AY_OFFSET);
gyro.setZAccelOffset(GYRO_AZ_OFFSET);
if (devStatus == 0) {
gyro.setDMPEnabled(true);
lastMicros = micros();
attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), dmpDataReady, RISING);
gyroIntStatus = gyro.getIntStatus();
packetSize = gyro.dmpGetFIFOPacketSize();
}else if(devStatus == 1) return EC_DMP_MEMORY_WRITING_FAILED;
else if(devStatus == 2) return EC_DMP_CONFIG_WRITING_FAILED;
}else return EC_NO_CONNECTION;
loops_before_calibration = 0;
return EC_NO_ERROR;
}
void GYRO::update(void){
//temperature = gyro.getTemperature()/340.0+36.53; //When discommenting this line i get rarely FIFO overflows, but without it, i have not recived eaither one
gyroscopeUpdated = false;
while (!interrupt && fifoCount < packetSize){
if (interrupt && fifoCount < packetSize){
fifoCount = gyro.getFIFOCount();
}
}
interrupt = false;
gyroIntStatus = gyro.getIntStatus();
fifoCount = gyro.getFIFOCount();
if ((gyroIntStatus & _BV(MPU6050_INTERRUPT_FIFO_OFLOW_BIT)) || fifoCount >= 1024){
gyro.resetFIFO();
fifoCount = gyro.getFIFOCount();
Serial.println(F("FIFO overflow!"));
}else if (gyroIntStatus & _BV(MPU6050_INTERRUPT_DMP_INT_BIT)){
while (fifoCount < packetSize) fifoCount = gyro.getFIFOCount();
gyro.getFIFOBytes(fifoBuffer, packetSize);
actualMicros = micros();
microsSpent = actualMicros - lastMicros;
lastMicros = actualMicros;
fifoCount -= packetSize;
gyro.dmpGetQuaternion(&q, fifoBuffer);
gyro.dmpGetGravity(&gravity, &q);
gyro.dmpGetYawPitchRoll(ypr, &q, &gravity);
gyro.dmpGetAccel(&rawAccelerometer, fifoBuffer);
gyro.dmpGetLinearAccel(&rawAccelerometer, &rawAccelerometer, &gravity);
//gyro.dmpGetLinearAccelInWorld(&rawAccelerometer, &rawAccelerometer, &q);
accelerometer.x = rawAccelerometer.x/8192.0*9.8;
accelerometer.y = rawAccelerometer.y/8192.0*9.8;
accelerometer.z = rawAccelerometer.z/8192.0*9.8;
gyroscope.x = ypr[2];
gyroscope.y = ypr[1]*-1;
gyroscope.z = ypr[0]*-1;
if(loops_before_calibration > CALIBRATION_LOOPS){
gyroscopeUpdated = true;
}else loops_before_calibration++;
}
}
Example code(To upload to arduino):
#include <GYRO.h>
#include <helper_3dmath.h>
GYRO gyro = GYRO();
VectorFloat gravity;
VectorFloat gyroscope;
VectorDouble accelerometer;
void setup() {
Serial.begin(115200);
Serial.println(gyro.begin());
}
void loop() {
gyro.update();
if(gyro.isGyroscopeUpdated()){
gravity = gyro.getGravity();
accelerometer = gyro.getAccelerometer();
gyroscope = gyro.getGyroscope();
Serial.print("gyroscope\t");
Serial.print(gyroscope.x * 180/M_PI);
Serial.print("\t");
Serial.print(gyroscope.y * 180/M_PI);
Serial.print("\t");
Serial.print(gyroscope.z * 180/M_PI);
Serial.print("\taccelerometer\t");
Serial.print(accelerometer.x);
Serial.print("\t");
Serial.print(accelerometer.y);
Serial.print("\t");
Serial.print(accelerometer.z);
Serial.print("\tgravity\t");
Serial.print(gravity.x);
Serial.print("\t");
Serial.print(gravity.y);
Serial.print("\t");
Serial.print(gravity.z);
Serial.print("\ttemperature\t");
Serial.print(gyro.getTemperature());
Serial.print(", micros: ");
Serial.println(gyro.getMicrosSpent());
}
}
You have to provide your own offsets. To obtain it, you can use this link
I hope this code is useful.

I know it is too late but maybe will help others...
The first MPU6050 initialization part in the setup() is done before even the mux initialized.
So you have to do the following, inside the setup(), at the right order:
initialize wire
initialize the outputs for the mux
select the first MPU using the right output levels
initialize the first MPU6050
select the second MPU using the right output levels
initialize the second MPU6050
select the third MPU using the right output levels
initialize the third MPU6050

Related

TTGO ESP32 + GSM 800l AT Commands

Good day all
I'm working on a project that takes sensor data and sends it to an online database using HTTP requests.Im ussing the TTGO esp32 sim 800 board, Everything works fine and all the data is stored in my online database the problem is that I cant get the AT commands to work, I need the Signal strength, battery voltage, and amount of Data available on the sim card.
Can someone please assist with this matter?
kind regards Hansie
Code
#include <HCSR04.h>
#define SOUND_SPEED 0.034
#define CM_TO_INCH 0.393701
// Set serial for debug console (to Serial Monitor, default speed 115200)
#define SerialMon Serial
// Set serial for AT commands (to SIM800 module)
#define SerialAT Serial1
// Configure TinyGSM library
#define TINY_GSM_MODEM_SIM800 // Modem is SIM800
#define TINY_GSM_RX_BUFFER 1024 // Set RX buffer to 1Kb
// Define the serial console for debug prints, if needed
//#define DUMP_AT_COMMANDS
#include <Wire.h>
#include <TinyGsmClient.h>
#define uS_TO_S_FACTOR 1000000UL /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP 36 /* Time ESP32 will go to sleep (in seconds) 3600 seconds = 1 hour */
#define IP5306_ADDR 0x75
#define IP5306_REG_SYS_CTL0 0x00
// TTGO T-Call pins
#define MODEM_RST 5
#define MODEM_PWKEY 4
#define MODEM_POWER_ON 23
#define MODEM_TX 27
#define MODEM_RX 26
#define I2C_SDA 21
#define I2C_SCL 22
int deviceID=101;
const int trigPin = 5;
const int echoPin = 18;
//Calculation variable for depth
//define sound speed in cm/uS
long duration;
float distanceCm;
double damDepth =200;
// Your GPRS credentials
const char apn[] = "Vodacom APN"; // APN
const char gprsUser[] = ""; // GPRS User
const char gprsPass[] = ""; // GPRS Password
// SIM card PIN (leave empty, if not defined)
const char simPIN[] = "";
// Server details
const char server[] = "grow-with-pierre.com"; // domain name:
const char resource[] = "/post-data.php"; // resource path, for example: /post-data.php
const int port = 80; // server port number
// Keep this API Key value to be compatible with the PHP code
String apiKeyValue = "tPmAT5Ab3j7F9";
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, SerialMon);
TinyGsm modem(debugger);
#else
TinyGsm modem(SerialAT);
#endif
// I2C for SIM800 (to keep it running when powered from battery)
TwoWire I2CPower = TwoWire(0);
// TinyGSM Client for Internet connection
TinyGsmClient client(modem);
bool setPowerBoostKeepOn(int en)
{
I2CPower.beginTransmission(IP5306_ADDR);
I2CPower.write(IP5306_REG_SYS_CTL0);
if (en)
{
I2CPower.write(0x37); // Set bit1: 1 enable 0 disable boost keep on
} else
{
I2CPower.write(0x35); // 0x37 is default reg value
}
return I2CPower.endTransmission() == 0;
}
void setup()
{
Serial.begin(115200); // Starts the serial communication
pinMode(trigPin, OUTPUT); // Sets the trigPin as an Output
pinMode(echoPin, INPUT); // Sets the echoPin as an Input
// Set serial monitor debugging window baud rate to 115200
SerialMon.begin(115200);
// Start I2C communication
I2CPower.begin(I2C_SDA, I2C_SCL, 400000);
// Keep power when running from battery
bool isOk = setPowerBoostKeepOn(1);
SerialMon.println(String("IP5306 KeepOn ") + (isOk ? "OK" : "FAIL"));
// Set modem reset, enable, power pins
pinMode(MODEM_PWKEY, OUTPUT);
pinMode(MODEM_RST, OUTPUT);
pinMode(MODEM_POWER_ON, OUTPUT);
digitalWrite(MODEM_PWKEY, LOW);
digitalWrite(MODEM_RST, HIGH);
digitalWrite(MODEM_POWER_ON, HIGH);
// Set GSM module baud rate and UART pins
SerialAT.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
delay(3000);
// Restart SIM800 module, it takes quite some time
// To skip it, call init() instead of restart()
SerialMon.println("Initializing modem...");
modem.restart();
// use modem.init() if you don't need the complete restart
// Unlock your SIM card with a PIN if needed
if (strlen(simPIN) && modem.getSimStatus() != 3 )
{
modem.simUnlock(simPIN);
}
// Configure the wake up source as timer wake up
esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
}
void loop()
{
postData();
Serial.print(String(" Percentage: ") + depth());
// Put ESP32 into deep sleep mode (with timer wake up)
esp_deep_sleep_start();
}
String postData()
{
SerialMon.print("Connecting to APN: ");
SerialMon.print(apn);
if (!modem.gprsConnect(apn, gprsUser, gprsPass))
{
SerialMon.println(" fail");
}
else
{
SerialMon.println(" OK");
SerialMon.print("Connecting to ");
SerialMon.print(server);
if (!client.connect(server, port))
{
SerialMon.println(" fail");
}
else
{
SerialMon.println(" OK");
// Making an HTTP POST request
SerialMon.println("Performing HTTP POST request...");
String httpRequestData = "api_key=" + apiKeyValue + "&value1=" + String(deviceID)
+ "&value2=" + String(distanceCm) + "&value3=" + String(80) + "&value4=" + String(40) + ""+ "&value5=" + String(50) + "";
// then, use the httpRequestData variable below (for testing purposes without the BME280 sensor)
// String httpRequestData = "api_key=tPmAT5Ab3j7F9&value1=24.75&value2=49.54&value3=1005.14";
client.print(String("POST ") + resource + " HTTP/1.1\r\n");
client.print(String("Host: ") + server + "\r\n");
client.println("Connection: close");
client.println("Content-Type: application/x-www-form-urlencoded");
client.print("Content-Length: ");
client.println(httpRequestData.length());
client.println();
client.println(httpRequestData);
unsigned long timeout = millis();
while (client.connected() && millis() - timeout < 10000L)
{
// Print available data (HTTP response from server)
while (client.available())
{
char c = client.read();
SerialMon.print(c);
timeout = millis();
}
}
SerialMon.println();
// Close client and disconnect
client.stop();
SerialMon.println(F("Server disconnected"));
modem.gprsDisconnect();
SerialMon.println(F("GPRS disconnected"));
}
}
}
float depth() //Find Depth in cm
{
double persentage;
// Clears the trigPin
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
// Sets the trigPin on HIGH state for 10 micro seconds
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
// Reads the echoPin, returns the sound wave travel time in microseconds
duration = pulseIn(echoPin, HIGH);
// Calculate the distance
distanceCm = duration * SOUND_SPEED/2;
// Prints the distance in the Serial Monitor
Serial.print("Distance (cm): ");
Serial.println(distanceCm);
persentage = (distanceCm/damDepth)*100;
if(persentage>=100)
{
persentage=100;
}
else
{
persentage=100- persentage;
}
return persentage;
}
For at least some of the desired functions, it isn't necessary to push AT-commands.
Try signalStrength = modem.getSignalQuality(); instead. It works for me on the Lilygo T-Call SIM800L. You can check out TinyGSM's Github-page for additional commands or this handy class reference

SPI Problem Arduino Mega with pressure sensor MS5803-05BA

I need your help for a project.
I have actually 2 parallel sensors of the type: MS5803-05BA, which supports I2C and SPI connection. One sensor is on I2C bus and one sensor is on SPI. They are both sending to my Arduino Mega. The I2C works perfect with short cables.
Here the datasheet of the sensor:
https://www.amsys.de/downloads/data/MS5803-05BA-AMSYS-datasheet.pdf
For some informations who wants to do the same with I2C. Here you can find a good code. (You can find the other MS580X typs there too). For the communication between the sensor and the Arduino Mega you need an logic converter like this txs0108e, which can be bought with a break out board (you need pull up resistors on the sensor side!):
https://github.com/millerlp/MS5803_05
But to my problem: I have an sensor distance for about 3-5 meters and the I2C connections doesnt work. Yes I can try to fix the pullup resistors but it doesnt worked for me (I have tried some different lower resistors between 3-10kOhm). Therefore I want to switch to the SPI bus.
I have edit the code from https://github.com/millerlp/MS5803_05, https://github.com/vic320/Arduino-MS5803-14BA and https://arduino.stackexchange.com/questions/13720/teensy-spi-and-pressure-sensor.
The File is added. (You have to put the .h and .cpp files in the folder of the arduino code (.spi).
I have problems with the code from the SPI (ccp and header). There is no right communication. I have checked my cables twice. I couldnt find a problem and the connection with the txs0108e works for parallel I2C sensor. Both sensors are working on I2C.
Here is the main code (arduino .spi) for SPI and I2C parallel:
/_____ I N C L U D E S
#include <stdio.h>
#include <math.h>
#include <SPI.h>
#include <Wire.h>
#include "MS5803_05.h"
#include "MS5803_05_SPI.h"
const int miso_port = 50; //SDI
const int mosi_port = 51; //SDO
const int sck_port = 52; //SLCK
const int slaveSelectPin = 53; // CSB
MS_5803 sensor = MS_5803(512);
MS_5803_SPI sensor_spi = MS_5803_SPI(4096, slaveSelectPin);
void setup()
{
pinMode(miso_port, INPUT);
pinMode(mosi_port, OUTPUT);
pinMode(slaveSelectPin, OUTPUT);
pinMode(sck_port, OUTPUT);
Serial.begin(9600);
//SPI BUS
if (sensor_spi.initializeMS_5803_SPI()) {
Serial.println( "MS5803 SPI CRC check OK." );
}
else {
Serial.println( "MS5803 SPI CRC check FAILED!" );
}
//I2C BUS
delay(1000);
if (sensor.initializeMS_5803()) {
Serial.println( "MS5803 I2C CRC check OK." );
}
else {
Serial.println( "MS5803 I2C CRC check FAILED!" );
}
}
void loop()
{
Serial.println("SPI Sensor first pressure [mbar], than temperature[°C]:");
sensor_spi.readSensor();
// Show pressure
Serial.print("Pressure = ");
Serial.print(sensor_spi.pressure());
Serial.println(" mbar");
// Show temperature
Serial.print("Temperature = ");
Serial.print(sensor_spi.temperature());
Serial.println("C");
////********************************************************
Serial.println("");
Serial.println("I2C Sensor first pressure [mbar], than temperature[°C]:");
sensor.readSensor();
// Show pressure
Serial.print("Pressure = ");
Serial.print(sensor.pressure());
Serial.println(" mbar");
// Show temperature
Serial.print("Temperature = ");
Serial.print(sensor.temperature());
Serial.println("C");
delay(2000);
}
}
The first connection with SPI is here (.cpp):
#include "MS5803_05_SPI.h"
#include <SPI.h>
#define CMD_RESET 0x1E // ADC reset command
#define CMD_ADC_READ 0x00 // ADC read command
#define CMD_ADC_CONV 0x40 // ADC conversion command
#define CMD_ADC_D1 0x00 // ADC D1 conversion
#define CMD_ADC_D2 0x10 // ADC D2 conversion
#define CMD_ADC_256 0x00 // ADC resolution=256
#define CMD_ADC_512 0x02 // ADC resolution=512
#define CMD_ADC_1024 0x04 // ADC resolution=1024
#define CMD_ADC_2048 0x06 // ADC resolution=2048
#define CMD_ADC_4096 0x08 // ADC resolution=4096
#define CMD_PROM_RD 0xA0 // Prom read command
#define spi_write SPI_MODE3
#define spi_write2 SPI_MODE1
// Create array to hold the 8 sensor calibration coefficients
static unsigned int sensorCoeffs[8]; // unsigned 16-bit integer (0-65535)
// D1 and D2 need to be unsigned 32-bit integers (long 0-4294967295)
static uint32_t D1 = 0; // Store uncompensated pressure value
static uint32_t D2 = 0; // Store uncompensated temperature value
// These three variables are used for the conversion steps
// They should be signed 32-bit integer initially
// i.e. signed long from -2147483648 to 2147483647
static int32_t dT = 0;
static int32_t TEMP = 0;
// These values need to be signed 64 bit integers
// (long long = int64_t)
static int64_t Offset = 0;
static int64_t Sensitivity = 0;
static int64_t T2 = 0;
static int64_t OFF2 = 0;
static int64_t Sens2 = 0;
// Some constants used in calculations below
const uint64_t POW_2_33 = 8589934592ULL; // 2^33 = 8589934592
SPISettings settings_write(500000, MSBFIRST, spi_write);
SPISettings settings_write2(500000, MSBFIRST, spi_write2);
//-------------------------------------------------
// Constructor
MS_5803_SPI::MS_5803_SPI( uint16_t Resolution, uint16_t cs) {
// The argument is the oversampling resolution, which may have values
// of 256, 512, 1024, 2048, or 4096.
_Resolution = Resolution;
//Chip Select
_cs=cs;
}
boolean MS_5803_SPI::initializeMS_5803_SPI(boolean Verbose) {
digitalWrite( _cs, HIGH );
SPI.begin();
// Reset the sensor during startup
resetSensor();
if (Verbose)
{
// Display the oversampling resolution or an error message
if (_Resolution == 256 | _Resolution == 512 | _Resolution == 1024 | _Resolution == 2048 | _Resolution == 4096){
Serial.print("Oversampling setting: ");
Serial.println(_Resolution);
} else {
Serial.println("*******************************************");
Serial.println("Error: specify a valid oversampling value");
Serial.println("Choices are 256, 512, 1024, 2048, or 4096");
Serial.println("*******************************************");
}
}
// Read sensor coefficients
for (int i = 0; i < 8; i++ )
{
SPI.beginTransaction(settings_write2);
digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low
unsigned int ret;
unsigned int rC = 0;
SPI.transfer(CMD_PROM_RD + i * 2); // send PROM READ command
/*
ret = SPI.transfer(0x00); // send 0 to read the MSB
rC = 256 * ret;
ret = SPI.transfer(0x00); // send 0 to read the LSB
rC = rC + ret;
*/
// send a value of 0 to read the first byte returned:
rC = SPI.transfer( 0x00 );
rC = rC << 8;
rC |= SPI.transfer( 0x00 ); // and the second byte
sensorCoeffs[i] = (rC);
digitalWrite( _cs, HIGH );
delay(3);
}
//SPI.endTransaction(); // interrupt can now be accepted
// The last 4 bits of the 7th coefficient form a CRC error checking code.
unsigned char p_crc = sensorCoeffs[7];
// Use a function to calculate the CRC value
unsigned char n_crc = MS_5803_CRC(sensorCoeffs);
if (Verbose) {
for (int i = 0; i < 8; i++ )
{
// Print out coefficients
Serial.print("C");
Serial.print(i);
Serial.print(" = ");
Serial.println(sensorCoeffs[i]);
delay(10);
}
Serial.print("p_crc: ");
Serial.println(p_crc);
Serial.print("n_crc: ");
Serial.println(n_crc);
}
// If the CRC value doesn't match the sensor's CRC value, then the
// connection can't be trusted. Check your wiring.
if (p_crc != n_crc) {
return false;
}
// Otherwise, return true when everything checks out OK.
return true;
}
// Sends a power on reset command to the sensor.
void MS_5803_SPI::resetSensor() {
SPI.beginTransaction(settings_write);
digitalWrite(_cs, LOW); //csb_lo(); // pull CSB low to start the command
SPI.transfer(CMD_RESET); // send reset sequence
delay(3); // wait for the reset sequence timing delay(3)
digitalWrite(_cs, HIGH); //csb_hi(); // pull CSB high to finish the command
SPI.endTransaction(); // interrupt can now be accepted
}
The Code can be downloaded at: https://forum.arduino.cc/index.php?topic=670661.0
There you can find the schematic and output picture too.
Thanks a lot :).

SPI on ADE7953 board

So, I've been trying to emplement a SPI communication between the board and my arduino. In the board's manual, it says that it is required to send two bytes with the address I want to read/write and another byte to choose read or write (most significant bit tells you which will apply). However, my code does not seem to be running. Anyone care to help? Code
I've not used the actual Arduino SPI library, but I will offer you an Arduino snippet that will bitbang SPI instead. It will allow you to send some bytes just to see if everything is working. It might be useful to try another approach just to see if it works. You will need to change the pins and registers to match your target application.
#define PIN_SPIDATA 16
#define PIN_SPICLK 17
#define PIN_SPILOAD 18
#define REG_DECODEMODE 0x09
#define REG_INTENSITY 0x0A
#define REG_SCANLIMIT 0x0B
#define REG_SHUTDOWN 0x0C
#define REG_DISPLAYTEST 0x0F
void setup() {
// set ddr for sw spi pins
pinMode(PIN_SPICLK, OUTPUT);
pinMode(PIN_SPIDATA, OUTPUT);
pinMode(PIN_SPILOAD, OUTPUT);
setRegister(REG_INTENSITY, 0x04);
setRegister(REG_SCANLIMIT, 0x07);
setRegister(REG_SHUTDOWN, 0x01); // normal operation
setRegister(REG_DECODEMODE, 0x00); // pixels not integers
setRegister(REG_DISPLAYTEST, 0x00); // not in test mode
}
// sends a single byte by sw spi (no latching)
void putByte(uint8_t data)
{
uint8_t i = 8;
uint8_t mask;
while(i > 0) {
mask = 0x01 << (i - 1); // get bitmask
digitalWrite(PIN_SPICLK, LOW); // tick
if (data & mask){ // choose bit
digitalWrite(PIN_SPIDATA, HIGH); // set 1
}else{
digitalWrite(PIN_SPIDATA, LOW); // set 0
}
digitalWrite(PIN_SPICLK, HIGH); // tock
--i; // move to lesser bit
}
}
// sets register to the same byte value for all screens
void setRegister(uint8_t reg, uint8_t data)
{
digitalWrite(PIN_SPILOAD, LOW); // begin
for(uint8_t i = 0; i < numChips; ++i){
putByte(reg); // specify register
putByte(data); // send data
}
digitalWrite(PIN_SPILOAD, HIGH); // latch in data
digitalWrite(PIN_SPILOAD, LOW); // end
}

PPM output is noisy when reading from sensors over i2c

Please excuse me for the lengthiness of the problem but its beyond my knowhow, I dont know where else to go.
I am trying to send a PPM signal to a FlySkyi10 radio over the trainer cable. When using the PPM code below I am able to send the correct PPM signals to my radio.
//this programm will put out a PPM signal
//////////////////////CONFIGURATION///////////////////////////////
#define chanel_number 8 //set the number of chanels
#define default_servo_value 1500 //set the default servo value
#define PPM_FrLen 22500 //set the PPM frame length in microseconds (1ms = 1000µs)
#define PPM_PulseLen 300 //set the pulse length
#define onState 1 //set polarity of the pulses: 1 is positive, 0 is negative
#define sigPin 10 //set PPM signal output pin on the arduino
//////////////////////////////////////////////////////////////////
/*this array holds the servo values for the ppm signal
change theese values in your code (usually servo values move between 1000 and 2000)*/
int ppm[chanel_number];
void setup(){
//initiallize default ppm values
for(int i=0; i<chanel_number; i++){
ppm[i]= default_servo_value;
}
pinMode(sigPin, OUTPUT);
digitalWrite(sigPin, !onState); //set the PPM signal pin to the default state (off)
cli();
TCCR1A = 0; // set entire TCCR1 register to 0
TCCR1B = 0;
OCR1A = 100; // compare match register, change this
TCCR1B |= (1 << WGM12); // turn on CTC mode
TCCR1B |= (1 << CS11); // 8 prescaler: 0,5 microseconds at 16mhz
TIMSK1 |= (1 << OCIE1A); // enable timer compare interrupt
sei();
}
void loop(){
//put main code here
static int val = 1;
ppm[0] = ppm[0] + val;
if(ppm[0] >= 2000){ val = -1; }
if(ppm[0] <= 1000){ val = 1; }
delay(10);
}
ISR(TIMER1_COMPA_vect){ //leave this alone
static boolean state = true;
TCNT1 = 0;
if(state) { //start pulse
digitalWrite(sigPin, onState);
OCR1A = PPM_PulseLen * 2;
state = false;
}
else{ //end pulse and calculate when to start the next pulse
static byte cur_chan_numb;
static unsigned int calc_rest;
digitalWrite(sigPin, !onState);
state = true;
if(cur_chan_numb >= chanel_number){
cur_chan_numb = 0;
calc_rest = calc_rest + PPM_PulseLen;//
OCR1A = (PPM_FrLen - calc_rest) * 2;
calc_rest = 0;
}
else{
OCR1A = (ppm[cur_chan_numb] - PPM_PulseLen) * 2;
calc_rest = calc_rest + ppm[cur_chan_numb];
cur_chan_numb++;
}
}
}
But, the problem comes in when I read data from a sensor over i2c and some other functions. As soon as I use the i2c code, the PPM signal becomes noisy, and what should be a 1500ms signal, has noise of +/-20ms.
I dont want to make this post too bulky, I have used the i2c library for the LSM9DS0 to read sensor data. I have not used interrupts anywhere and I will have to have a closer look at the library. unfortunately i dont understand much of it. The simplified code for reading from the seensors is below. the website for the libraries is here: https://learn.adafruit.com/adafruit-lsm9ds0-accelerometer-gyro-magnetometer-9-dof-breakouts/arduino-code
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_LSM9DS0.h>
#include <Adafruit_Sensor.h> // not used in this demo but required!
// i2c
Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0();
// You can also use software SPI
//Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(13, 12, 11, 10, 9);
// Or hardware SPI! In this case, only CS pins are passed in
//Adafruit_LSM9DS0 lsm = Adafruit_LSM9DS0(10, 9);
void setupSensor()
{
// 1.) Set the accelerometer range
lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_2G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_4G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_6G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_8G);
//lsm.setupAccel(lsm.LSM9DS0_ACCELRANGE_16G);
// 2.) Set the magnetometer sensitivity
lsm.setupMag(lsm.LSM9DS0_MAGGAIN_2GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_4GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_8GAUSS);
//lsm.setupMag(lsm.LSM9DS0_MAGGAIN_12GAUSS);
// 3.) Setup the gyroscope
lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_245DPS);
//lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_500DPS);
//lsm.setupGyro(lsm.LSM9DS0_GYROSCALE_2000DPS);
}
void setup()
{
#ifndef ESP8266
while (!Serial); // will pause Zero, Leonardo, etc until serial console opens
#endif
Serial.begin(9600);
Serial.println("LSM raw read demo");
// Try to initialise and warn if we couldn't detect the chip
if (!lsm.begin())
{
Serial.println("Oops ... unable to initialize the LSM9DS0. Check your wiring!");
while (1);
}
Serial.println("Found LSM9DS0 9DOF");
Serial.println("");
Serial.println("");
}
void loop(void)
{
/* Get a new sensor event */
sensors_event_t accel, mag, gyro, temp;
lsm.getEvent(&accel, &mag, &gyro, &temp);
// print out accelleration data
Serial.print("Accel X: "); Serial.print(accel.acceleration.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(accel.acceleration.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(accel.acceleration.z); Serial.println(" \tm/s^2");
// print out magnetometer data
Serial.print("Magn. X: "); Serial.print(mag.magnetic.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(mag.magnetic.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(mag.magnetic.z); Serial.println(" \tgauss");
// print out gyroscopic data
Serial.print("Gyro X: "); Serial.print(gyro.gyro.x); Serial.print(" ");
Serial.print(" \tY: "); Serial.print(gyro.gyro.y); Serial.print(" ");
Serial.print(" \tZ: "); Serial.print(gyro.gyro.z); Serial.println(" \tdps");
// print out temperature data
Serial.print("Temp: "); Serial.print(temp.temperature); Serial.println(" *C");
Serial.println("**********************\n");
delay(250);
}
Does anyone have an suggestions?
I changed the method of reading data from the sensors to SPI, which solved the problem. All noise in the ppm signal has been eliminated.

Why Arduino int can't count over 14464?

I got some problem about reading from MPU6050 and then write to SD card.
Actually I could successfully do the read-and-write, but I found Arduino UNO can't count over 14464!?
I set every line of my data that is:
count, time(millis()), ax, ay, az, gx, gy, gz
It could record the data right till count to 14464 (I) and it will end the loop automated.
It really bothers me... and it seems no one face this problem before.
Here is my code:
#include "I2Cdev.h"
#include "MPU6050.h"
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
#include "Wire.h"
#endif
MPU6050 accelgyro;
//SD card here
#include <SPI.h>
#include <SD.h>
File myFile;
//////////Global Variable Here//////////
int16_t ax, ay, az;
int16_t gx, gy, gz;
int count = 1;
//set sec & count_limit
int set_time = 1000 * 60;
int count_limit = 80000;
int BTN = 7;
// uncomment "OUTPUT_READABLE_ACCELGYRO" if you want to see a tab-separated
// list of the accel X/Y/Z and then gyro X/Y/Z values in decimal. Easy to read,
// not so easy to parse, and slow(er) over UART.
#define OUTPUT_READABLE_ACCELGYRO
//Set LED
#define R_PIN 8
#define G_PIN 9
bool blinkState_R = false;
bool blinkState_G = false;
void setup() {
// configure Arduino LED for
pinMode(R_PIN, OUTPUT);
pinMode(G_PIN, OUTPUT);
pinMode(BTN, INPUT);
digitalWrite(G_PIN, HIGH);
// join I2C bus (I2Cdev library doesn't do this automatically)
#if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
Wire.begin();
#elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
Fastwire::setup(400, true);
#endif
// initialize serial communication
// (38400 chosen because it works as well at 8MHz as it does at 16MHz, but
// it's really up to you depending on your project)
Serial.begin(38400);
// initialize device
Serial.println("Initializing I2C devices...");
accelgyro.initialize();
accelgyro.setFullScaleAccelRange(MPU6050_ACCEL_FS_2);
// verify connection
Serial.println("Testing device connections...");
Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed");
// use the code below to change accel/gyro offset values
accelgyro.setXGyroOffset(59);
accelgyro.setYGyroOffset(42);
accelgyro.setZGyroOffset(-8);
accelgyro.setXAccelOffset(1359);
accelgyro.setYAccelOffset(-1620);
accelgyro.setZAccelOffset(1917);
/////////////////////////////////////////////////////////////////////
//SD card Initailize
/////////////////////////////////////////////////////////////////////
Serial.print("Initializing SD card...");
if (!SD.begin(4)) {
Serial.println("initialization failed!");
digitalWrite(R_PIN, HIGH);
return;
}
Serial.println("initialization done.");
digitalWrite(R_PIN, LOW);
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// open a new file and immediately close it:
Serial.println("Creating example.txt...");
myFile = SD.open("example.txt", FILE_WRITE);
myFile.close();
// Check to see if the file exists:
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
// delete the file:
Serial.println("Removing example.txt...");
SD.remove("example.txt");
if (SD.exists("example.txt")) {
Serial.println("example.txt exists.");
}
else {
Serial.println("example.txt doesn't exist.");
}
delay(3000);
////////////////////////////////////////////////////////////////////////////////
//SD END
////////////////////////////////////////////////////////////////////////////////
digitalWrite(G_PIN, LOW);
}
void loop() {
// read raw accel/gyro measurements from device
accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
blinkState_R = !blinkState_R;
digitalWrite(R_PIN, blinkState_R);
// these methods (and a few others) are also available
//accelgyro.getAcceleration(&ax, &ay, &az);
//accelgyro.getRotation(&gx, &gy, &gz);
////////////////////////////////////////////
// Write to SD Card
///////////////////////////////////////////
// write data to file
if(count <= count_limit ){
myFile = SD.open("IMU_LOG.txt", FILE_WRITE);
Serial.print(count);Serial.print("\t"); myFile.print(count); myFile.print("\t");
Serial.print(millis()); Serial.print("\t"); myFile.print(millis()); myFile.print("\t");
Serial.print(ax); Serial.print("\t"); myFile.print(ax); myFile.print("\t");
Serial.print(ay); Serial.print("\t"); myFile.print(ay); myFile.print("\t");
Serial.print(az); Serial.print("\t"); myFile.print(az); myFile.print("\t");
Serial.print(gx); Serial.print("\t"); myFile.print(gx); myFile.print("\t");
Serial.print(gy); Serial.print("\t"); myFile.print(gy); myFile.print("\t");
Serial.print(gz); Serial.print("\n"); myFile.print(gz); myFile.print("\n");
myFile.close();
delay(5);
blinkState_G = !blinkState_G;
digitalWrite(G_PIN, blinkState_G);
}else{
while(1){
Serial.print("Process done.\n");
digitalWrite(G_PIN, OUTPUT);
delay(2000);
}
count= count + 1 ;
}
You should be getting a compiler warning here.
int count_limit = 80000;
The maximum value of int on your platform is 32,767. When you set an int to something larger, the behavior is undefined, which is bad news because it means that your program is incorrect.
In this particular case, you might notice that 80000 = 14464 + 216, which explains why it stopped at 14464, if int is 16 bits long.
You will need to use long if you want to count higher than 65,535.
long count_limit = 80000L;
long count = 1;

Resources