Hi
I have made a code to send gyro x,y and z values every 4 seconds from one arduino to another using nrf24l01.
here at transmitter side i am using arduino pro mini. so now i want to make changes in transmitting data, when there is change in the gyro z axis only then arduino pro mini should come out of sleep and send data.
can some one please help me to do this changes.
here is my transmitter code which i have to send data every 4 seconds.
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>
#include <SPI.h>
#include "RF24.h"
#include <Wire.h>
// Changing transmitter num
#define TRANSMITER_NUM 0 // or 1
const int MPU = 0x68; // MPU6050 I2C address
float AccX, AccY, AccZ;
float GyroX, GyroY, GyroZ;
float accAngleX, accAngleY, gyroAngleX, gyroAngleY, gyroAngleZ;
float roll, pitch, yaw;
float AccErrorX, AccErrorY, GyroErrorX, GyroErrorY, GyroErrorZ;
float elapsedTime, currentTime, previousTime;
const uint64_t talking_pipes[2] = { 0xF0F0F0F0D1LL, 0xF0F0F0F0C2LL };
struct DataPacket {
int voltage;
int x;
int y;
int z;
};
RF24 radio(7,8);
void watchdogSetup(void)
{
wdt_reset();
WDTCSR = bit (WDCE) | bit (WDE) | bit (WDIE) | bit (WDP3)| bit (WDP2) | bit (WDP1);
}
void disableHardware() {
// radio.sleep(); // Set the radio transceiver in sleep mode
radio.powerDown(); // NOTE: The radio MUST be powered back up again manually
power_spi_disable(); // Disable the Serial Peripheral Interface module.
power_timer0_disable(); // Disable the Timer 0 module..
power_timer1_disable(); // Disable the Timer 1 module.
power_timer2_disable(); // Disable the Timer 2 module
power_twi_disable(); // Disable the Two Wire Interface module.
//power_usart0_disable(); // Disable the USART 0 module.
ADCSRA &= ~(1 << ADEN); // Ensure AD control register is disable before power disable
power_adc_disable(); // Disable the Analog to Digital Converter module
//adxl.setLowPower(true);
}
void enableHardware() {
power_spi_enable(); // Enable the Serial Peripheral Interface module.
power_timer0_enable(); // Enable the Timer 0 module..
power_timer1_enable(); // Enable the Timer 1 module.
power_timer2_enable(); // Enable the Timer 2 module
power_twi_enable(); // Enable the Two Wire Interface module.
#ifdef SERIAL_PRINT
power_usart0_enable(); // Enable the USART 0 module.
#endif
power_adc_enable(); // Enable the Analog to Digital Converter module
radio.powerUp(); // Power up the radio after sleeping
}
void enterSleep(void)
{ADCSRA = 0;
sleep_enable();
disableHardware();
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
MCUSR = 0;
watchdogSetup();
sleep_cpu();
sleep_disable();
enableHardware();
}
void setup()
{
Serial.begin(9600);
radio.begin();
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS);
radio.setChannel(0x50);
radio.openWritingPipe(talking_pipes[TRANSMITER_NUM]);
getBandgap();
#ifdef SERIAL_PRINT
Serial.println("Initialisation complete.");
#endif
}
ISR (WDT_vect)
{
wdt_disable(); // disable watchdog
} // end of WDT_vect
const long InternalReferenceVoltage = 1100; // Adjust this value to your board's specific internal BG voltage
int getBandgap ()
{
ADMUX = bit (REFS0) | bit (MUX3) | bit (MUX2) | bit (MUX1);
ADCSRA |= bit( ADSC ); // start conversion
while (ADCSRA & bit (ADSC))
{ } // wait for conversion to complete (toss this measurement)
ADCSRA |= bit( ADSC ); // start conversion
while (ADCSRA & bit (ADSC))
{ } // wait for conversion to complete
int results = (((InternalReferenceVoltage * 1024) / ADC) + 5) / 10;
return results;
}
int cnt=0;
void loop()
{
bool sendValue = false;
DataPacket data;
cnt++;
if (cnt >=1 ) { // send EVERY time wakeup happens
cnt = 0;
sendValue = true;
}
if (sendValue) {
cnt = 0;
data.voltage = getBandgap();
Wire.begin(); // Initialize comunication
Wire.beginTransmission(MPU); // Start communication with MPU6050 // MPU=0x68
Wire.write(0x6B); // Talk to the register 6B
Wire.write(0x00); // Make reset - place a 0 into the 6B register
Wire.endTransmission(true);
Wire.beginTransmission(MPU);
Wire.write(0x3B); // Start with register 0x3B (ACCEL_XOUT_H)
Wire.endTransmission(false);
Wire.requestFrom(MPU, 6, true);
AccX = (Wire.read() << 8 | Wire.read()) / 16384.0; // X-axis value
AccY = (Wire.read() << 8 | Wire.read()) / 16384.0; // Y-axis value
AccZ = (Wire.read() << 8 | Wire.read()) / 16384.0; // Z-axis value
// Calculating Roll and Pitch from the accelerometer data
accAngleX = (atan(-1*AccY / sqrt(pow(AccX, 2) + pow(AccZ, 2))) * 180 / PI) - 0.58; // AccErrorX ~(0.58) See the calculate_IMU_error()custom function for more details
accAngleY = (atan(-1 * AccX / sqrt(pow(AccY, 2) + pow(AccZ, 2))) * 180 / PI) + 1.58; // AccErrorY ~(-1.58)
Wire.beginTransmission(MPU);
Wire.write(0x43); // Gyro data first register address 0x43
Wire.endTransmission(false);
Wire.requestFrom(MPU, 6, true);
GyroX = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroY = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroZ = (Wire.read() << 8 | Wire.read()) / 131.0;
GyroX = GyroX + 0.56; // GyroErrorX ~(-0.56)
GyroY = GyroY - 2; // GyroErrorY ~(2)
GyroZ = GyroZ + 0.79; // GyroErrorZ ~ (-0.8)
gyroAngleX = gyroAngleX ; // deg/s * s = deg
gyroAngleY = gyroAngleY;
yaw = GyroZ;
roll = 0.96 * gyroAngleX + 0.04 * accAngleX;
pitch = 0.96 * gyroAngleY + 0.04 * accAngleY;
data.x = accAngleX;
data.y = accAngleY;
data.z = yaw;
Serial.print(data.x);
Serial.print("/");
Serial.print(data.y);
Serial.print("/");
Serial.println(data.z);
radio.write( &data, sizeof(data) );
}
enterSleep();
}