Verify Successful, MCU does nothing

#include <Servo.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // use I2C interface
Adafruit_Sensor *bmp_temp = bmp.getTemperatureSensor();
Adafruit_Sensor *bmp_pressure = bmp.getPressureSensor();

Servo servo; // Create a servo instance.

void setup() {
  Serial.begin(9600);
  Serial.println(F("BMP280 Sensor event test"));

  if (!bmp.begin()) {
    Serial.println(F("Could not find a valid BMP280 sensor, check wiring!"));
    while (1) delay(10);
  }

  /* Default settings from datasheet. */
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

  bmp_temp->printSensorDetails();
}

void loop() {
  sensors_event_t temp_event, pressure_event;
  bmp_temp->getEvent(&temp_event);
  bmp_pressure->getEvent(&pressure_event);

  Serial.print(F("Temperature = "));
  Serial.print(temp_event.temperature);
  Serial.println(" *C");

  Serial.print(F("Pressure = "));
  Serial.print(pressure_event.pressure);
  Serial.println(" hPa");

  if (pressure_event.pressure < 951) {
    servo.attach(24); //PWM pin servo is attached to
  }

  while (pressure_event.pressure > 950) {
    servo.write(0); // moves servo to 0 degrees
    delay(1000);
    servo.write(180); // moves servo to 180 degrees
    delay(1000);
  }
  delay(2000);
}

Sketch uses 35160 bytes (13%) of program storage space. Maximum is 262144 bytes.
Atmel SMART device 0x10010005 found
Device : ATSAMD21G18A
Chip ID : 10010005
Version : v2.0 [Arduino:XYZ] Mar 5 2016 17:46:52
Address : 8192
Pages : 3968
Page Size : 64 bytes
Total Size : 248KB
Planes : 1
Lock Regions : 16
Locked : none
Security : false
Boot Flash : true
BOD : true
BOR : true
Arduino : FAST_CHIP_ERASE
Arduino : FAST_MULTI_PAGE_WRITE
Arduino : CAN_CHECKSUM_MEMORY_BUFFER
Erase flash
done in 0.903 seconds

Write 35440 bytes to flash (554 pages)
[==============================] 100% (554/554 pages)
done in 0.281 seconds

Verify 35440 bytes of flash with checksum.
Verify successful
done in 0.024 seconds
CPU reset.

Adafruit BMP280 Library

My code compiles and uploads, however it does nothing when the serial monitor is pulled up. The code works when I use the BMP280 example code and when I use the Servo example code but doesn't work when I combine them. I do not even get pressure or temperature readings on the serial monitor with this code. My end goal is to have the servo move when the pressure is low enough but it will be starting at sea level and I don't want it to be "engaged" or "turned on" until it reaches a certain altitude. It will be responsible for deploying a parachute.

I am unsure why I am not even getting readings from my sensor anymore and I'm wondering if there is a better way to "initialize" my servo above a certain altitude.

Could you point out to me where you have assigned the pin for the servo to use?

1 Clue4U

void setup() { // Attach the Servo variable to a pin: myservo.attach(servoPin); }

That while loop will block forever since you are not re-reading the "pressure_event". The while loop should not be in the code, there are better ways of doing the job.

Idaho I have the pin assigned during this "if" statement in the hopes that the servo wouldn't be "armed" until it reached a high enough altitude. Am I only able to assign the pin during "void setup"?

Danois would the MCU not just "move past" or "skip" that part of the code when the "pressure_event" is below 950? Or does it stick there waiting for the "pressure_event" to be above 950? You said it's not re-reading the "pressure_event" so I'm assuming its stuck in the while loop and not skipping to re-read back at the top of the entire loop.

It seems like my method of activating the servo is the issue. How would you guys suggest I go about that differently?

It makes no sense to first attach the servo when the pressure is below 951. If the pressure remains above 950, the servo is never attached and the movement in the while loop will do nothing. Your while loop will start when the pressure is above 950 and then it will never end because the pressure is not updated and therefore does not change whilst in the while loop.

Hello
add a timer() function and a small FSM to control the servo behaviour.

I should have mentioned that it will be used on a weather balloon so I'm not worried about if the pressure will change. The pressure will for sure change and I will need to dial in the numbers so lets not get hung up on 950 and 951, those will change. I'm mostly wondering how to make the servo work on the descent and not the ascent.

You must attach the servo in the "setup" method. Then you must check the pressure for each iteration of "loop", if the pressure increases the balloon is in descent and the servo must be moved.

EDIT: I meant descent not ascent.

The pressure would decrease as the balloon ascended. I would like for the chute to deploy at 2000 feet or so but I don't want it to deploy before it reaches 2000 feet on the way up. I only want it to deploy on the way down. If the servo can only be attached in the setup, then how could I make sure it doesn't move during ascent? I want it to deploy based on the altitude.

What is the difference between accent and decent with the way you are setup up for measuring altitude?

If I was ascending and measuring air pressure, I'd expect the last few previous measurements would be higher then the current set of measurements.

What would you read for a decent? Say you were to store the minimum air pressure score. When the air pressure begins to rise over the minimum value recorded would that be a decent?

I'm now working with something to compare the previous pressure reading to move the servo. Something like this

int Pvalue = pressure_event.pressure;

if (pressure_event.pressure > Pvalue && pressure_event.pressure > 1000)

The servo is assigned in void setup. I'm looking for the MCU to compare each reading with the last so when it's at the desired altitude AND descending, it will deploy the chute. Although I'm wondering if my "int Pvalue = pressure_event.pressure;" is the way to do it or if I should be using another kind of variable.

Would it make more sense to have a rolling average?

If one reading just happens to be lower then the previous reading, but the rocket is still going up, but the code deploys the chute from just one reading.

moving average library

Is the air pressure value an int or a float?

The 2 BMP680's I am using give their values as floats.

Here we go now. Idaho thank you for making me realize I needed to switch to floats not int. The code also was wrong for the BMP280. For some reason it interchanges "BMP" and "BMP280" with reckless abandon. THIS code compiles and works, it shows up on the serial monitor and the sensors respond to my physical input.

I also switched to an "if" statement so the servo wont move unless the current altitude is less than the previous altitude AND the current altitude is lower than a specific altitude. I set that specific altitude to 530 so I could test it holding it over my head in my living room.

Idaho I see what you're saying though about having a rolling average and one reading just happening to be lower than the previous one which would deploy the chute on the ascent. I haven't addressed that yet but I'm thinking I can also add a timer to my "if" statement. Balloons have like a 2 hour ascent so I could lock it out with an easy "millis()" function. I would have to time it with my calculated ascent speed and how long it takes to get to the desired altitude. I could ballpark it and over estimate by like 10 minutes and still be fine.

The eagle eyed among you will also see that I added an accelerometer and gyroscope to it. Thats just for fun.

#include <Adafruit_LSM6DS33.h>
#include <Adafruit_BMP280.h>
#include <Servo.h>
#include <Wire.h>
#include <SPI.h>

Adafruit_LSM6DS33 lsm6ds33; // accelerometer, gyroscope
Adafruit_BMP280 bmp;     // temperautre, barometric pressure
Servo servo;  // create servo object to control a servo

float temperature, pressure, altitude;
float accel_x, accel_y, accel_z;
float gyro_x, gyro_y, gyro_z;
float A;

void setup() {
  lsm6ds33.begin_I2C();
  servo.attach(5);  // attaches the servo on pin whatever to the servo object
  bmp.begin();
  servo.write(90);
  
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */

A = 1018.75;  //hPa at sea level on each day. 538m is home altitude for reference

}
void loop() {
  pressure = bmp.readPressure();
  altitude = bmp.readAltitude(A);

  sensors_event_t accel;
  sensors_event_t gyro;
  sensors_event_t temp;
  lsm6ds33.getEvent(&accel, &gyro, &temp);
  accel_x = accel.acceleration.x;
  accel_y = accel.acceleration.y;
  accel_z = accel.acceleration.z;
  gyro_x = gyro.gyro.x;
  gyro_y = gyro.gyro.y;
  gyro_z = gyro.gyro.z;

  Serial.print("Acceleration: X:");
  Serial.print(accel_x);
  Serial.print(" Y:");
  Serial.print(accel_y);
  Serial.print(" Z:");
  Serial.print(accel_z);
  Serial.println(" m/s^2");

  delay(250);

  Serial.print("Barometric pressure: ");
  Serial.print(pressure);
  Serial.print(" hPa Altitude: ");
  Serial.print(altitude);
  Serial.println(" m");

  if (bmp.readAltitude(A) < altitude && bmp.readAltitude(A) < 530) {
    servo.write(90); // moves servo to 90 degrees
    Serial.println("Deploy Chute");     
  } else {
    Serial.println("No Deploy");
  }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.