Hi everyone!
I made a variometer using by arduino nano which is works with gy-63(ms5611 pressure, temperature ) module.
And also I added an oled screen to see values.
But I'm having a problem about code or device. I'm not sure what problem is.
The problem is; the code that you can find below, screen and buzzer doesn't works at the same time. I'm using a passive buzzer connected to d9 and d10 pins to use toneac library with pwm signals.
All the components are working perfect when I code single.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <toneAC.h>
#include <MS5611.h>
MS5611 ms5611; // MS5611 sensor object
#define SCREEN_WIDTH 128 // Screen width
#define SCREEN_HEIGHT 64 // Screen height
#define OLED_RESET -1 // Screen reset pin, this screen doesn't have a reset pin
#define NUM_PRESSURES 64
#define NUM_TOTALS 16
uint32_t pressure[NUM_PRESSURES];
uint32_t old_total[NUM_TOTALS];
int pressure_index = 0;
int total_index = 0;
uint32_t total;
int current_tone = 0;
int beep_time = 0;
// Create the OLED screen object
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
// Start serial communication
Serial.begin(9600);
// Initialize OLED screen (using address 0x3C)
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3C
Serial.println(F("Failed to initialize OLED display"));
while (1); // Stop if the screen fails to initialize
}
// Clear the OLED screen
display.clearDisplay();
// Play startup sound
toneAC(388, 4);
delay(70);
toneAC(0);
delay(30);
toneAC(590, 4);
delay(70);
// Initialize the MS5611 sensor
if (!ms5611.begin()) {
Serial.println("MS5611 sensor not detected. Check the connections.");
while (1); // Stop if the sensor is not detected
}
uint32_t p = ms5611.readPressure();
total = p * NUM_PRESSURES;
// Initialize the pressure array with the first value
for (int i = 0; i < NUM_PRESSURES; i++) {
pressure[i] = p;
}
// Initialize the old_total array with the first total value
for (int i = 0; i < NUM_TOTALS; i++) {
old_total[i] = total;
}
toneAC(0);
// Display "Merhaba" (Hello) on the screen
display.setTextSize(1); // Set text size
display.setTextColor(SSD1306_WHITE); // Set text color to white
display.setCursor(0, 0); // Set starting position (top left corner)
display.print(F("Merhaba")); // Print "Merhaba" (Hello)
display.display(); // Update the display
delay(2000); // Display for 2 seconds
}
void loop() {
// Read new pressure and update the total pressure
total -= pressure[pressure_index];
pressure[pressure_index] = ms5611.readPressure(); // Read current pressure from MS5611
total += pressure[pressure_index];
// Calculate the pressure change rate
int32_t rate = total - old_total[total_index];
old_total[total_index] = total;
// Reset the indices for the pressure and total arrays
pressure_index++;
total_index++;
if (pressure_index >= NUM_PRESSURES) pressure_index = 0;
if (total_index >= NUM_TOTALS) total_index = 0;
// Adjust tone frequency based on the pressure change rate
if (rate < -50) {
if (beep_time < 5) {
toneAC(1000 - rate / 2); // Increase frequency based on pressure change
} else {
toneAC(0); // Turn off tone after a certain period
}
} else if (rate > 50) {
// Set frequency based on the pressure change rate
float f = 1000.0 + 40000.0 * 1.0 / ((float)rate); // Formula for higher frequencies
toneAC((int)f);
} else {
// Turn off the tone if the pressure change rate is small
toneAC(0);
}
// Increase beep_time and reset if necessary
beep_time++;
if (beep_time >= 10) beep_time = 0;
// Continuously display "Merhaba" on the screen
display.clearDisplay(); // Clear the screen
display.setCursor(0, 0); // Set starting position
display.print(F("Merhaba")); // Print "Merhaba" (Hello)
display.display(); // Update the display
delay(500); // Wait for 500ms
}
"Doesn't work" covers a lot of ground. If you could state precisely and in detail exactly what happens and what you were expecting to happen, that would be of great help.
Buzzer must be beep depending to pressure difference rate. On the screen must be shown temperature, altitude etc.
But unfortunately both of device does not responds. serial monitor message: oled screen couldn't start
Edit: I have tried to code one by one. They are doing their job as should be
Edit 2: on the code that I shared with the post, screen command is about writing 'merhaba' on the oled screen. I did this so that it would work independently of the ms5611 sensor. However, nothing works.
Since you were asked to be precise and detailed, and you didn't mention any error messages that are present in the code, I'll have to assume that there weren't any. I'm afraid I have no other ideas in that case. But good luck figuring it out.
Is that the exact message, or is the message "Failed to initialize OLED display"? If so, then there is not enough dynamic memory (ram) available for the display buffer.
Yes this is the correct message'Failed to initialize OLED display'. So what should I do to solve this issue?
I saw a few post about problems using oled screen together with buzzer on the forum
I'm not familiar with any conflicts between an oled screen and buzzer.
The major problem you are having is that the display needs 1024 bytes of ram at run-time for the display buffer. There are other libraries for the display that use a smaller buffer, such as U8g2 with a frame buffer, or libraries for displaying text only, which needs no buffer.
You can try to reduce the ram usage by making sure the F() macro is used for all the text literals in the Serial.print() statements, but you are already using that in most places.
I will try and share the result.
By the way the screen works individually(without buzzer). It shows all the results measured by ms5611.
But probably it uses too much memory to control buzzer
Add this to what other libraries are using. Then, when the code runs, the OLED library attempts to reserve 1024 + bytes and there is not sufficient available.
Can we assume you are using an Uno? You forgot to include this very basic detail in your posts. There are many types of Arduino with different capabilities and different memory limits.
Your sensor library returns pressure in Pascals (Pa) Atmospheric pressure is approximately 100,000 Pa. This is too large to fit into an int on Uno, so you must use a long int (also called uint32_t). But a long int takes 4 bytes compared to 2 for an int.
Maybe you could divide all the pressure readings by 10 before storing them into the array. This would give readings around 10,000, which would fit into an int. Then your array would take only half as many bytes. When calculating the average, you could multiply the result by 10 to get back to Pascals.
In both condition code worked.
I'm using arduino nano.
Device should be works as a vario meter for paragliding. So device must be detect all the pressure changes and must give voice warning immediately.
When I changed (memory usages) values as you find above, voice commands doesn't work as I want(as must be).
Now I'm thinking to use arduino mega or another chipset like ESP etc.
Please tell me am I wrong?
I have amended your code to remove the MS5611 library and any calls to it. When I upload the code to my nano V3, I hear the startup beeps and see "Merhaba" displayed correctly.
I can see that much of the Nano's RAM memory is being used:
Global variables use 863 bytes (42%) of dynamic memory, leaving 1185 bytes for local variables. Maximum is 2048 bytes.
When the code runs, at least 1024 bytes will be reserved by the OLED library, leaving only perhaps 150 bytes remaining. Far too little for reliable operation.
But I think I figured out why. I had already installed a MS5611 library from library manager, by Rob Tillart. The IDE was picking that other library up.
Removing it now and re-testing.
UPDATE: it is compiling now:
Global variables use 897 bytes (43%) of dynamic memory, leaving 1151 bytes for local variables. Maximum is 2048 bytes.