Атмосферный датчик BMP280 вместо BMP180, проблема.

feonor12
Offline
Зарегистрирован: 20.11.2017

Доброго времени суток, форумчане. Ну новичек, все дела, вы поняли, в каждом сообщении наверное это пишут, не буду...

Возникла проблема. Есть устройство, в котором используется барометр BMP180. У меня более новый датчик BMP280, к которому не подходит библиотека предыдущего. Установил нужные библиотеки, проверил приложеным примером - работает. Попытался заменить библиотеку в исходном коде на нужную - ловлю ошибку. В общем вопрос такой: как мне прикрутить к этому коду мой датчик?

исходный код:

[code]
/*
 * Raketa-mini или альтиметр в бюджетном варианте.
 * Программа для записи летных характеристик ракеты
 * Используется контролер микро ардуино,
 * барометр BMP085 (лучше использовать BMP180)
 * ЗУМ(6), кнопка(8) для стирания, светодиод(7) для индикации 
 * база транзистора (9) для вышибного заряда 
 * ПЗУ используется встроенное всего 1кБайт, поэтому
 * высота записывается 255 раз с выборкой ttt мсек.
 * в 0 адрес записывается максимальная высота
 * Высота округляется до 1м.
 */
 
//Добавляем библиотеки
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>

Adafruit_BMP085 dps = Adafruit_BMP085();      // Digital Pressure Sensor 

long Al1 = 0; // высота с барометра
int hmax = 0; // максимальная высота полета
int led = 7;  // номер порта для светодиода
int knop = 8; // номер порта для кнопки очистки памяти 
int fire = 9; // номер порта для вышибного заряда
int p = 6;    // номер порта пьезодинамик
int hh = 3; // высота с которой начинается запись полета в память
// а так же высота снижения при котором сработает вышибной заряд
unsigned long tt = 0; // сюда записывает время начало полета
unsigned long t = 1; //время кратное ttt
int ttt = 80; //будем записывать каждые ttt мсек (от 20 до 1000 мсек)
//20 = 255*20=5100 это примерно 5 сек полета
//1000 = 255 секунд полета
boolean rec = 0;// 0=память чистая, 1=в памяти хранятся данные о полете 

void setup()
{
  pinMode(led, OUTPUT);     
  pinMode(p, OUTPUT); //объявляем пин как выход
  pinMode(knop, INPUT);     
  pinMode(fire, OUTPUT);     
  digitalWrite(fire, LOW);
  Wire.begin();
  Serial.begin(9600);  // запуск последовательного порта
  dps.init(MODE_STANDARD, 0, true);

}

void loop()
{
  digitalWrite(led, HIGH);   //включаем светодиод
// Проверяем есть ли данные
 if (EEPROM.read(0)>1)//если по адресу 0 есть данные подымаем флаг
   {
     rec = 1;
   }  
 int h = 0;//высота полета
 if (rec == 1)//если есть данные в памяти
 {
   vyvod();//вывод информации на экран
   while (digitalRead(knop) == 0) //ждем нажатия кнопки стирания
   {
   delay (100); 
   }
   digitalWrite(led, HIGH);   //включаем светодиод
   delay (200); 
   digitalWrite(led, LOW);   //выключаем светодиод
   for (int i = 0; i < 512; i++)
     EEPROM.write(i, 0);//стираем память
//   EEPROM_int_write(0, 0);
   Serial.println("Clear");     // печатает в порт
   rec = 0;//ставим флаг - память чистая
 }else //если данных нет
 {
   do
   {
     dps.getAltitude(&Al1);//берем высоту из барометра
     h=round(Al1*0.01);//округляем высоту до 1м
   }   while (h < hh);// ждем когда ракета подымится на высоту hh
   digitalWrite(led,LOW);
   tt = millis();//запоминаем сколько прошло времени с начало работы контролера
   // начинаем записывать данные
   for (int i=2; i<511; i++)//начиная со 2 адресса
  { 
     if (hmax < h)//если текущая высота выше максимальной(значит идет набор высоты)
       {
         hmax = h;//записываем новое значение максимальной высоты
         EEPROM_int_write(0, hmax);//по адресу 0 записываем макс.высоту
       }
     else //начинаем снижатся
       {
         if (hmax > (h+hh))//ждем пока не опустится ниже hh от макс.высоты
           {
           digitalWrite(fire, HIGH);   // активируем вышибной заряд
           }
       } 
     EEPROM_int_write(i, h);//записываем текущую высоту по адресу i
     while ((t*ttt)>(millis()-tt)) ;
     t++;
     dps.getAltitude(&Al1);
     h=round(Al1*0.01);
     i++;
  }
  t = 1;
//  Serial.print(" mil=");     // печатает в порт
//  Serial.println(millis()-tt);     // печатает в порт
  rec=1;
  digitalWrite(fire, LOW);   // turn the LED on (HIGH is the voltage level)
  while(millis()>0)// будет пищать пока есть питание :)
  {
    tone (p, 500); //включаем на 500 Гц
    delay(100); //ждем 100 Мс
    tone(p, 1000); //включаем на 1000 Гц
    delay(100); //ждем 100 Мс
  }
 }
}


// запись в пямять по 2 байта
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
// чтение из памяти по 2 байта
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// вывод на экран результат полета
int vyvod(){
  Serial.println(" Polet =");     // печатает в порт
  Serial.print(" max=");     // печатает в порт
  Serial.println(EEPROM_int_read(0));     // печатает в порт
  for (int i=2; i<512; i++)
  {
    digitalWrite(led, HIGH);
    Serial.println(EEPROM_int_read(i));     // печатает в порт
    i++;
    digitalWrite(led, LOW);
    delay (50);
  }
  
}  

[/code]

Код, который я изменил (изменения только в строчках 18-23)

[code]
/*
 * Raketa-mini или альтиметр в бюджетном варианте.
 * Программа для записи летных характеристик ракеты
 * Используется контролер микро ардуино,
 * барометр BMP085 (лучше использовать BMP180)
 * ЗУМ(6), кнопка(8) для стирания, светодиод(7) для индикации 
 * база транзистора (9) для вышибного заряда 
 * ПЗУ используется встроенное всего 1кБайт, поэтому
 * высота записывается 255 раз с выборкой ttt мсек.
 * в 0 адрес записывается максимальная высота
 * Высота округляется до 1м.
 */
 
//Добавляем библиотеки
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C

Adafruit_BMP280 dps = Adafruit_BMP280();      // Digital Pressure Sensor 


long Al1 = 0; // высота с барометра
int hmax = 0; // максимальная высота полета
int led = 7;  // номер порта для светодиода
int knop = 8; // номер порта для кнопки очистки памяти 
int fire = 9; // номер порта для вышибного заряда
int p = 6;    // номер порта пьезодинамик
int hh = 3; // высота с которой начинается запись полета в память
// а так же высота снижения при котором сработает вышибной заряд
unsigned long tt = 0; // сюда записывает время начало полета
unsigned long t = 1; //время кратное ttt
int ttt = 80; //будем записывать каждые ttt мсек (от 20 до 1000 мсек)
//20 = 255*20=5100 это примерно 5 сек полета
//1000 = 255 секунд полета
boolean rec = 0;// 0=память чистая, 1=в памяти хранятся данные о полете 

void setup()
{
  pinMode(led, OUTPUT);     
  pinMode(p, OUTPUT); //объявляем пин как выход
  pinMode(knop, INPUT);     
  pinMode(fire, OUTPUT);     
  digitalWrite(fire, LOW);
  Wire.begin();
  Serial.begin(9600);  // запуск последовательного порта
  dps.init(MODE_STANDARD, 0, true);

}

void loop()
{
  digitalWrite(led, HIGH);   //включаем светодиод
// Проверяем есть ли данные
 if (EEPROM.read(0)>1)//если по адресу 0 есть данные подымаем флаг
   {
     rec = 1;
   }  
 int h = 0;//высота полета
 if (rec == 1)//если есть данные в памяти
 {
   vyvod();//вывод информации на экран
   while (digitalRead(knop) == 0) //ждем нажатия кнопки стирания
   {
   delay (100); 
   }
   digitalWrite(led, HIGH);   //включаем светодиод
   delay (200); 
   digitalWrite(led, LOW);   //выключаем светодиод
   for (int i = 0; i < 512; i++)
     EEPROM.write(i, 0);//стираем память
//   EEPROM_int_write(0, 0);
   Serial.println("Clear");     // печатает в порт
   rec = 0;//ставим флаг - память чистая
 }else //если данных нет
 {
   do
   {
     dps.getAltitude(&Al1);//берем высоту из барометра
     h=round(Al1*0.01);//округляем высоту до 1м
   }   while (h < hh);// ждем когда ракета подымится на высоту hh
   digitalWrite(led,LOW);
   tt = millis();//запоминаем сколько прошло времени с начало работы контролера
   // начинаем записывать данные
   for (int i=2; i<511; i++)//начиная со 2 адресса
  { 
     if (hmax < h)//если текущая высота выше максимальной(значит идет набор высоты)
       {
         hmax = h;//записываем новое значение максимальной высоты
         EEPROM_int_write(0, hmax);//по адресу 0 записываем макс.высоту
       }
     else //начинаем снижатся
       {
         if (hmax > (h+hh))//ждем пока не опустится ниже hh от макс.высоты
           {
           digitalWrite(fire, HIGH);   // активируем вышибной заряд
           }
       } 
     EEPROM_int_write(i, h);//записываем текущую высоту по адресу i
     while ((t*ttt)>(millis()-tt)) ;
     t++;
     dps.getAltitude(&Al1);
     h=round(Al1*0.01);
     i++;
  }
  t = 1;
//  Serial.print(" mil=");     // печатает в порт
//  Serial.println(millis()-tt);     // печатает в порт
  rec=1;
  digitalWrite(fire, LOW);   // turn the LED on (HIGH is the voltage level)
  while(millis()>0)// будет пищать пока есть питание :)
  {
    tone (p, 500); //включаем на 500 Гц
    delay(100); //ждем 100 Мс
    tone(p, 1000); //включаем на 1000 Гц
    delay(100); //ждем 100 Мс
  }
 }
}


// запись в пямять по 2 байта
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
// чтение из памяти по 2 байта
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// вывод на экран результат полета
int vyvod(){
  Serial.println(" Polet =");     // печатает в порт
  Serial.print(" max=");     // печатает в порт
  Serial.println(EEPROM_int_read(0));     // печатает в порт
  for (int i=2; i<512; i++)
  {
    digitalWrite(led, HIGH);
    Serial.println(EEPROM_int_read(i));     // печатает в порт
    i++;
    digitalWrite(led, LOW);
    delay (50);
  }
  
}  

[/code]

ошибка, которую я получаю

Arduino: 1.8.6 Hourly Build 2017/11/07 04:33 (Windows 7), Плата:"Arduino Pro or Pro Mini, ATmega328P (5V, 16 MHz)"

D:\Паялка\Ардуино\arduino-nightly\libraries\Adafruit_BMP280_Library-master\examples\bmp280test\Raketa_mini\Raketa_mini.ino: In function 'void setup()':

Raketa_mini:49: error: 'class Adafruit_BMP280' has no member named 'init'

Raketa_mini:49: error: 'MODE_STANDARD' was not declared in this scope

D:\Паялка\Ардуино\arduino-nightly\libraries\Adafruit_BMP280_Library-master\examples\bmp280test\Raketa_mini\Raketa_mini.ino: In function 'void loop()':

Raketa_mini:81: error: 'class Adafruit_BMP280' has no member named 'getAltitude'

Raketa_mini:104: error: 'class Adafruit_BMP280' has no member named 'getAltitude'

exit status 1
'class Adafruit_BMP280' has no member named 'init'

Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
"Показать подробный вывод во время компиляции"

Заранее благодарен, мучаюсь уже долго, надеюсь на Вашу помощь. 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ну, чего тут, ну нет у класса Adafruit_BMP280 методов init и getAltitude. Нету и взять негде. Да и константа MODE_STANDARD в данной библиотеке не определена.

feonor12 пишет:

как мне прикрутить к этому коду мой датчик?. 

Либо переписать код так, чтобы не использовать несуществующие методы, либо найти библиотеку в которой они есть.

feonor12
Offline
Зарегистрирован: 20.11.2017

то есть простой правкой тут не отделатсья? Код переписать я не смогу, именно по этому обратился сюда.  Хорошо, я смотрел код библиотеки, он не такой и большой, в таком слуае может можно добавить этот метод в библиотеку? 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

feonor12 пишет:

то есть простой правкой тут не отделатсья? Код переписать я не смогу, именно по этому обратился сюда.  Хорошо, я смотрел код библиотеки, он не такой и большой, в таком слуае может можно добавить этот метод в библиотеку? 

Думаю, что можно, но наверняка там аналогичный и так есть.

feonor12
Offline
Зарегистрирован: 20.11.2017

Как я и писал с самого начала - тут именно в этом и проблема, в том, что я меняю библиотеки. Я смотрел код и менял поб себя на столько, на сколько понимаю. А понимаю я немного.

sadman41
Offline
Зарегистрирован: 19.10.2016

Думаю, что dps.init(...) можно заменить на dps.begin(), а вот с getAltitude() что делать - ума не приложу. Видимо скетч очень старый, ибо в библиотеке с изменениями, сделанными четыре года назад (https://github.com/adafruit/Adafruit-BMP085-Library), уже нет этого метода, а имеется readAltitude(float seaLevelhPa), в вашем же скетче передается высота, а не давление. Т.е. тут еще нужно посмотреть, что было в той, старой, библиотеке.

feonor12
Offline
Зарегистрирован: 20.11.2017

У меня есть два примера программ для этого датчика, и в обоих используется библиотека BMP085.h , а не Adafruit_BMP085.h 

Я так посмотрел, getAltitude в нем упоминается, в 86 строчке.

https://github.com/jarzebski/Arduino-BMP085-BMP180/blob/master/BMP085.h

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

feonor12 пишет:

Я так посмотрел, getAltitude в нем упоминается, в 86 строчке.

Так она ж константная, сама в себе и ни на что не влияет

double BMP085::getAltitude(double pressure, double seaLevelPressure)
{
    return (44330.0f * (1.0f - pow((double)pressure / (double)seaLevelPressure, 0.1902949f)));
}

Просто допишите её в другой класс и ничего не изменится.

Только, у Вас беда в том, что Вы даже не знаете где смотреть надо. Вы совсем ни строчки не пониманаете и просто хотите взять готовую программу, чтобы она заработала? Тогда, Вам, думаю, лучше всё же обратиться в "Ищу исполнителя". Здесь Вы будете очень долго мучиться.

sadman41
Offline
Зарегистрирован: 19.10.2016

ЕвгенийП пишет:

Так она ж константная, сама в себе и ни на что не влияет

Так я для этого и оставил подсказку ТС, чтобы он сам понял, что нужно подставлять в readAltitude(...).Библиотеку и не нужно даже править - просто подумать и в своем скетче изменить пару строк.

feonor12
Offline
Зарегистрирован: 20.11.2017

ЕвгенийП пишет:

 Вы совсем ни строчки не пониманаете

Ну пару может и понимаю...)

заменил init на begin, getAltitude на readAltitude  и в целом строчка вышла float Al1 =  bmp.readAltitude();

скетч скомпилировался без ошибок, но не уверен, выполняет ли он дальше свои функции...

[code]
/*
 * Raketa-mini или альтиметр в бюджетном варианте.
 * Программа для записи летных характеристик ракеты
 * Используется контролер микро ардуино,
 * барометр BMP085 (лучше использовать BMP180)
 * ЗУМ(6), кнопка(8) для стирания, светодиод(7) для индикации 
 * база транзистора (9) для вышибного заряда 
 * ПЗУ используется встроенное всего 1кБайт, поэтому
 * высота записывается 255 раз с выборкой ttt мсек.
 * в 0 адрес записывается максимальная высота
 * Высота округляется до 1м.
 */
 
//Добавляем библиотеки
#include <EEPROM.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BMP280.h>

Adafruit_BMP280 bmp; // I2C

//Adafruit_BMP280 dps = Adafruit_BMP280();      // Digital Pressure Sensor 


//long Al1 = 0; // высота с барометра
int hmax = 0; // максимальная высота полета
int led = 7;  // номер порта для светодиода
int knop = 8; // номер порта для кнопки очистки памяти 
int fire = 9; // номер порта для вышибного заряда
int p = 6;    // номер порта пьезодинамик
int hh = 3; // высота с которой начинается запись полета в память
// а так же высота снижения при котором сработает вышибной заряд
unsigned long tt = 0; // сюда записывает время начало полета
unsigned long t = 1; //время кратное ttt
int ttt = 80; //будем записывать каждые ttt мсек (от 20 до 1000 мсек)
//20 = 255*20=5100 это примерно 5 сек полета
//1000 = 255 секунд полета
boolean rec = 0;// 0=память чистая, 1=в памяти хранятся данные о полете 

void setup()
{
  pinMode(led, OUTPUT);     
  pinMode(p, OUTPUT); //объявляем пин как выход
  pinMode(knop, INPUT);     
  pinMode(fire, OUTPUT);     
  digitalWrite(fire, LOW);
  Wire.begin();
  Serial.begin(9600);  // запуск последовательного порта
  bmp.begin();

}

void loop()
{
  digitalWrite(led, HIGH);   //включаем светодиод
// Проверяем есть ли данные
 if (EEPROM.read(0)>1)//если по адресу 0 есть данные подымаем флаг
   {
     rec = 1;
   }  
 int h = 0;//высота полета
 if (rec == 1)//если есть данные в памяти
 {
   vyvod();//вывод информации на экран
   while (digitalRead(knop) == 0) //ждем нажатия кнопки стирания
   {
   delay (100); 
   }
   digitalWrite(led, HIGH);   //включаем светодиод
   delay (200); 
   digitalWrite(led, LOW);   //выключаем светодиод
   for (int i = 0; i < 512; i++)
     EEPROM.write(i, 0);//стираем память
//   EEPROM_int_write(0, 0);
   Serial.println("Clear");     // печатает в порт
   rec = 0;//ставим флаг - память чистая
 }else //если данных нет
 {
   do
   {
float Al1 =  bmp.readAltitude();//берем высоту из барометра
     h=round(Al1*0.01);//округляем высоту до 1м
   }   while (h < hh);// ждем когда ракета подымится на высоту hh
   digitalWrite(led,LOW);
   tt = millis();//запоминаем сколько прошло времени с начало работы контролера
   // начинаем записывать данные
   for (int i=2; i<511; i++)//начиная со 2 адресса
  { 
     if (hmax < h)//если текущая высота выше максимальной(значит идет набор высоты)
       {
         hmax = h;//записываем новое значение максимальной высоты
         EEPROM_int_write(0, hmax);//по адресу 0 записываем макс.высоту
       }
     else //начинаем снижатся
       {
         if (hmax > (h+hh))//ждем пока не опустится ниже hh от макс.высоты
           {
           digitalWrite(fire, HIGH);   // активируем вышибной заряд
           }
       } 
     EEPROM_int_write(i, h);//записываем текущую высоту по адресу i
     while ((t*ttt)>(millis()-tt)) ;
     t++;
float Al1 = bmp.readAltitude();
     h=round(Al1*0.01);
     i++;
  }
  t = 1;
//  Serial.print(" mil=");     // печатает в порт
//  Serial.println(millis()-tt);     // печатает в порт
  rec=1;
  digitalWrite(fire, LOW);   // turn the LED on (HIGH is the voltage level)
  while(millis()>0)// будет пищать пока есть питание :)
  {
    tone (p, 500); //включаем на 500 Гц
    delay(100); //ждем 100 Мс
    tone(p, 1000); //включаем на 1000 Гц
    delay(100); //ждем 100 Мс
  }
 }
}


// запись в пямять по 2 байта
void EEPROM_int_write(int addr, int num) {
  byte raw[2];
  (int&)raw = num;
  for(byte i = 0; i < 2; i++) EEPROM.write(addr+i, raw[i]);
}
// чтение из памяти по 2 байта
int EEPROM_int_read(int addr) {   
  byte raw[2];
  for(byte i = 0; i < 2; i++) raw[i] = EEPROM.read(addr+i);
  int &num = (int&)raw;
  return num;
}
// вывод на экран результат полета
int vyvod(){
  Serial.println(" Polet =");     // печатает в порт
  Serial.print(" max=");     // печатает в порт
  Serial.println(EEPROM_int_read(0));     // печатает в порт
  for (int i=2; i<512; i++)
  {
    digitalWrite(led, HIGH);
    Serial.println(EEPROM_int_read(i));     // печатает в порт
    i++;
    digitalWrite(led, LOW);
    delay (50);
  }
  
}  

[/code]

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

feonor12 пишет:
не уверен, выполняет ли он дальше свои функции...
Так ото ж ...

feonor12
Offline
Зарегистрирован: 20.11.2017

да, не выполняет...

sadman41
Offline
Зарегистрирован: 19.10.2016

Как вы это поняли? Не исключено, что выполняет, просто не так, как вы ожидаете.

feonor12
Offline
Зарегистрирован: 20.11.2017

sadman41 пишет:

Как вы это поняли? Не исключено, что выполняет, просто не так, как вы ожидаете.

собрал устройство на макетной плате, залил скетч и запустил. При включении ардуино шлет в порт серию данных, а точнее -1 секунд 15, и все. Она и должна слать, но когда получит результат полетных данных. Но алгоритм не выполняется, ждать после включения взлета (подъем на три метра), начинать записывать данные и ждать падения (спуск на 3 метра), активировать систему спасения, звуковой маяк и начинать слать данные в порт, пока не будет нажата кнопка сброса (не ресет, а предусмотренная схемой)

sadman41
Offline
Зарегистрирован: 19.10.2016

Могу вам только посоветовать на той же плате залить пример из адафруитовской библиотеки, убедиться, что данные с сенсора поступают и их размерность не отличается от тех, что были при BMP085. А дальше - тыкать Serial.println() в места, где производятся вычисления и сравнения. Скорее всего у вас в районе 84-й строки не выполняется условие и нужно понять - почему.

feonor12
Offline
Зарегистрирован: 20.11.2017

Заработало, вроде. Код, видимо, правильный. Нужно еще несколько раз тесты повторить, что бы убедится. Но работает. Запитал от повербанка и запихнул в... банку, дурацкий каламбур. Примитивным вакуумным насосом откачал давление, через примерно 13 сек. сработал звуковой маяк. Считал данные, регистрируются, устройство считает, что подымается (за счет снижения давления). Это отобразилось в мониторе порта. Как я понял, звуковой маяк (порт 6) активируется, когда заканчивается память. Но запал (порт 9) - только когда будет выполнено условие, что устройство опустилось на три метра. Я это понял на основе эмпирических методов. Когда я успел за 13 сек.  откачать воздух и открыть крышку, что бы давление возрасло, запал сработал. В данных тоже показало, что устройство снижалось. Работает значит.  В принципе все устраивает, только вот автор скетча заявляет, что памяти хватает на 20 сек. при этом он использовал ардуино с атмегой 168, у меня же 328, в ней на сколько знаю больше встроенной памяти, но хватает на меньшее время... как так? 

Может банально выйти, что ракета пролетит больше 13 секунд, и система спасения не сработает...

sadman41
Offline
Зарегистрирован: 19.10.2016
ATMega168 - Data EEPROM (bytes) 512
ATMega328 - Data EEPROM (bytes) 1024
 
См. циклы в районе работы с EEPROM, например - строки 73, 88, 143 - видите заточку под 168-ю мегу?

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Если не хватит килобайта EEPROM, можно прилепить внешнюю I2C память на AT24C256 (256 kbit = 32 kbyte serial EEPROM) -  https://playground.arduino.cc/Code/I2CEEPROM. Думаю, что ваша ракета не полетит со скоростью, опережающей работу I2C.

...правда, придётся скетчик поперепахать...

feonor12
Offline
Зарегистрирован: 20.11.2017

Вижу. И не вижу). Я же говорил, что не разбираюсь... Если я вас правильно понимаю, то в строчке 73 и 143 нужно заменить значения с 512 на 1024. А в строчке 88 на 1023, оставив один байт для чего-то там...предпологаю для записи максимальной высоты...

feonor12
Offline
Зарегистрирован: 20.11.2017

да я бы с удовольствие добавил карту памяти, тем более модуль под нее есть. Но как вы понимаете и видите - сделать я этого не смогу, по крайней мере на данной стадии. Я ардуино начал изучать ровно тогда, когда начал строить именно эту ракету. То есть неделю назад. 

sadman41
Offline
Зарегистрирован: 19.10.2016

feonor12 пишет:

Вижу. И не вижу). Я же говорил, что не разбираюсь...

Ну, тут незамысловатый код - достаточно включить логическое мышление, которое у вас есть, раз имитационные опыты с откачкой воздуха проводите. Данные пишутся в энергонезависимую память, такую как EEPROM. Соответственно - в коде нужно найти места, где с ней работают и посмотреть, в каких пределах изменяется адресация. В данный момент, как я вижу, адрес ограничен ячейкой #512, что соответствует 512 байтам 168-й атмеги. Отсюда вывод - если есть больше памяти, нужно сдвигать ограничение в бОльшую сторону.

sadman41
Offline
Зарегистрирован: 19.10.2016

feonor12 пишет:

да я бы с удовольствие добавил карту памяти, тем более модуль под нее есть. Но как вы понимаете и видите - сделать я этого не смогу, по крайней мере на данной стадии. Я ардуино начал изучать ровно тогда, когда начал строить именно эту ракету. То есть неделю назад.

Мне кажется, что карта памяти не лучший вариант в ракете, которую может ударить обо что-то - механическое соединение в слоте. Да и сложный для вас программный интерфейс, энергопотребление...  EEPROM в восьминогом DIP-корпусе, который можно надежно припаять и закрепить - нормальное бюджетное решение. На мой взгляд.

Кстати, у 280-го боша есть набор разных режимов работы, которые будут давать результаты с большей скоростью или большей точностью, а так же встроенная функция оверсемплинга и фильтр, позволяющий сгладить шумы АЦП (см даташит). Правда, адафруитовская библиотека их не позволяет выставить, но возможно, что иные варианты, включая самописные (я баловался как-то с этим сенсором), позволят их активировать.

feonor12
Offline
Зарегистрирован: 20.11.2017

Да, это сработало! Время выросло ровно в 2 раза. Наконец-то можно переходить от макетки к изготовлению! Очень благодарен за помощь, особенно вам, sadman41, за вашу уникальную способность не только помочь, но и заставить учиться! 

Но я, возможно, еще обращусь) 

feonor12
Offline
Зарегистрирован: 20.11.2017

на счет разных режимов работы этого датчика. Да, я знаю, что они есть. Именно по этому мне пришлось удалить код, который задавал режим работы для датчика, который изначально использовался в этом скетче. Я выкладывал в первом посте сообщение ошибки, там фигурирует этот момент, MODE_STANDARD вроде. Я пытался заменить на MODE_NORMAL, как это указано для этого датчика, но была ошибка. Я удалил , по примеру из библиотеки. Так что этот вопрос остался для меня открытым. 

andrikll
Offline
Зарегистрирован: 04.08.2013

Интересный датчик и устройство. Почитал поискал, хотелось бы разобраться с настройкой его режимов.

Datasheet почитал, страницы 12, 24 

Разрешение находится в регистре 0xF4 2,3,4 ,бит. Если на максимум поставить разрешение то записать нужно это (см. скетч)?  (адрес датчика взял из библиотеки). Как не затронуть остальные биты адреса и как их перписывать если вписать нужно значение 0?

#include <Wire.h>

void setup()
{
     Wire.beginTransmission(0х77);
    Wire.write(0xF4);
    Wire.write(0b00011100); //разрешение измерения 2,3,4 бит
    Wire.endTransmission();
}

void loop  () {}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Установка режима производится так: в BMP280_REGISTER_CONTROL (0xF4) нужно заслать  ((BMP280_OSRS_T << 6) | (BMP280_OSRS_P << 3) | BMP280_MODE), где BMP280_OSRS_T и BMP280_OSRS_P - значения из Table 5 даташита (она для osrs_t, но соответствие oversampling и бинарного значения справедливо и для osrs_p, по-моему), а BMP280_MODE - из Table 10 (0x01 для Forced-режима или 0x03 для Normal).

Предварительно (так как конверсия/цикл конверсий начинается после установки значений в 0xF4) и однократно в BMP280_REGISTER_CONFIG (0xF5)  можно закинуть ((BMP280_STANDBY_TIME_MS << 6)| (BMP280_FILTER_COEF << 3) |  BMP280_SPI_ENABLE)). BMP280_STANDBY_TIME_MS из Table 11, BMP280_FILTER_COEF - из Table 6, BMP280_SPI_ENABLE = 0, если используется I2C.

С режимами есть небольшая заморочка - в Normal mode конверсии осуществляются циклически и результаты перемещаются во внутренний массив. Команда чтения с I2C останавливает перемещение до того момента, пока чтение не будет завершено. Т.е. для того, чтобы получить данные с одного замера, а не с разных, массив нужно читать одной трансмиссией, а не по байту за трансмиссию. Таким образом, если вы не можете обеспечить такой режим считывания, следует перевести датчик в Forced mode, в котором он будет работать как BMP180 и запускать конверсию, когда попросят. Однако и тут есть ловушка - при операции чтения в этом режиме вы получаете не актуальные данные, а данные прошлого замера. Т.е. для редкого получения актуальных данных необходимо проводить две конверсии сразу и только после этого проводить чтение, если же конверсии запускаются в быстром цикле, то достаточно однократного запуска конверсии и последующего забора данных.

Надеюсь, что это вам поможет ))

PS. замену режима можно провести чтением из регистра (положим 0xF4), наложением битовой маски и засылкой обратно. Но проще - тупо закидывать туда байт целиком.

andrikll
Offline
Зарегистрирован: 04.08.2013

Можно ли забрасывать значения вида (для BMP280_OSRS_P) Wire.write(0b111<<3); ?

 

 

sadman41
Offline
Зарегистрирован: 19.10.2016

Не советую. Потому что в этом случае все остальные биты придут туда нулевыми. А непредсказуемого поведения датчика вам не нужно.

andrikll
Offline
Зарегистрирован: 04.08.2013

Как то так?


#include <Wire.h>

 byte byte_f4;
 byte mask_f4;

void setup()
{   Wire.begin();
    Wire.beginTransmission(0х77);
    Wire.write(0xF4);
​    byte_f4=Wire.read(); 
    mask_f4=0b00011100;  mask_f4=0b00011100 & 0xF4;
    Wire.write(mask_f4); //разрешение измерения 2,3,4 бит
    Wire.endTransmission();
}

void loop  () {}

p.s. ошибок навыдавало

p.p.s. исправил чар на байт

sadman41
Offline
Зарегистрирован: 19.10.2016

Наложение маски - да, в принципе. Только излишние присвоения не нужны. А остальное... Байт как char зачем объявлять, если есть byte? 0b0.. не пишут, пишут B00011100. В одной трансмиссии, как мне помниться, нельзя одновременно и чтение и запись делать. Чтение - одна трансмиссия, запись - вторая.

andrikll
Offline
Зарегистрирован: 04.08.2013

Не понял я в чем была ошибка, переписал часть от руки и все пошло. (какой то обратный слэш был причиной, я его не видел-невидимый). Почитал, переписал, исправил.


#include <Wire.h>

 byte byte_f4;
 byte mask_f4;

void setup()
{
  Wire.begin(); 
  Wire.requestFrom(0x77,1);
  byte_f4=Wire.read();
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write(0xF4);        // sends five bytes
  mask_f4=B00011100;  mask_f4=B00011100 & byte_f4;
  Wire.write(mask_f4);              // sends one byte  
  Wire.endTransmission();    // stop transmitting
}

void loop()
{}

 

sadman41
Offline
Зарегистрирован: 19.10.2016

И что, работает? По моему мнению нужно действовать так: 

  // Читаем с 0xF4
  Wire.beginTransmission(0x77);   // С устройства 0x77
  Wire.write(0xF4);               // Регистр 0xF4
  Wire.endTransmission(false);    // Трансмиссию не останавливаем 
  Wire.requestFrom(0x77, 1);      // 1 байт
  byte_f4 = Wire.read();          // читаем
  Wire.endTransmission(true);     // Трансмиссия завершена
  // Накладываем маску
  byte_f4 = byte_f4 & B00011100;
  // Пишем в 0xF4
  Wire.beginTransmission(0x77);   // В устройство 0x77
  Wire.write(0xF4);               // Регистр 0xF4
  Wire.write(byte_f4);            // Значение
  Wire.endTransmission(true);     // Трансмиссия завершена

 

andrikll
Offline
Зарегистрирован: 04.08.2013

Я вас понял. В примерх которые смотрел реквест без трансмишн

Здесь я ошибку допустил  Wire.requestFrom(0x77, 1);

нужно

Wire.requestFrom(0xF4, 1);

Dimston
Offline
Зарегистрирован: 19.12.2017

feonor12 с Вами можно как нибудь связаться, есть общий интерес моё  мыло  vakulenko78@mail.ru   dmitriyvakulenko1978@gmail.com