реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> FOSP01 - датчик атмосферного давления и температуры, Скачут показания
alux
сообщение Aug 28 2007, 19:12
Сообщение #16


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Попробовал на другом датчике (FOSP01A). Та же фигня. 07.gif Температура и давление=0. Прошу помощи в данной проблеме. Исчерпал все варианты. help.gif
Go to the top of the page
 
+Quote Post
sls_
сообщение Aug 29 2007, 06:56
Сообщение #17


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-03-07
Пользователь №: 25 875



Цитата(alux @ Aug 28 2007, 23:12) *
Попробовал на другом датчике (FOSP01A). Та же фигня. 07.gif Температура и давление=0. Прошу помощи в данной проблеме. Исчерпал все варианты. help.gif


Здравствуйте alux!
Бегло просмотрев Ваш исходник, не нашол в нем сброса датчика, который на сколько я помню его и запускает.
Что то типа этого:
void FOSP01Reset(void)
{
bXCLR = 0;
I2c_dly ();
bXCLR = 1;
}
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 29 2007, 07:24
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(sls_ @ Aug 29 2007, 09:56) *
не нашол в нем сброса датчика, который на сколько я помню его и запускает.

Спасибо, за ответ. Функция fosp01Init(); вызывается раньше в main().
Код
void main(void)
.......
  fosp01Init();
.......
PressureTemperatureMeasure();
......
}

/////////////////
void fosp01Init(void)
{
  DDRD |= (1<<XCLR);      //XCLR - на выход

  PORTD &= ~(1<<XCLR);
  delay_ms(100);
  PORTD |= (1<<XCLR);     //сброс FOSP01-A
}

В даташите ничего не сказано про длительность импульса сброса. Пробовал разные. Или импульс сброса надо давать перед КАЖДЫМ преобразованием?
В JTAG проконтролировал каждый шаг в функции fosp01RxValue(n). Каждый байт успешно отправлен. А в ответ - 0.
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 29 2007, 11:33
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Глас вопиющего в пустыне... Видимо, никому нет дела. У меня вывод напрашивается только такой: Оба датчика бракованные. 05.gif
Go to the top of the page
 
+Quote Post
sls_
сообщение Aug 29 2007, 11:58
Сообщение #20


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-03-07
Пользователь №: 25 875



Дело есть, времяни нет ....
Цитата(alux @ Aug 29 2007, 11:24) *
В даташите ничего не сказано про длительность импульса сброса. Пробовал разные. Или импульс сброса надо давать перед КАЖДЫМ преобразованием?

Нет достаточно один раз сбросить.
На мой взгляд три варианта:
1. не проходит сброс
2. нет частоты (не та частота) на MCLK
3. брак
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 29 2007, 12:29
Сообщение #21


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(sls_ @ Aug 29 2007, 14:58) *
1. не проходит сброс

Подаю отрицательный импульс длительностью от 100мсек. Пробовал 3сек. Может как-то по особенному надо сбрасывать? Типа 20 раз подать импульсов на XCLR...
Цитата(sls_ @ Aug 29 2007, 14:58) *
2. нет частоты (не та частота) на MCLK

Частота формируется микросхемой реального времени DS1388. Осцилографом не смотрел, но уверен, что там 32768Гц. Второе. Если бы проблема была бы в этом, то коэффициенты не считывались.
Цитата(sls_ @ Aug 29 2007, 14:58) *
3. брак

Сразу два датчика? Маловероятно. Очень похоже , что ошибка в программе. Только все здесь просто как 2х2, ... но не работает wacko.gif
Просто черная полоса какая-то. То АЦП AD7730 сгорело по непонятной причине. Теперь вот это...

Цитата
Добавлено

Один датчик выдает:
Цитата
C1: 8609
C2: -24317
C3: 175
C4: 0
C5: 28576
C6: -24159
C7: -24124
A: 3
B: 22
C: 6
D: 161
D1: 0
D2: 0


Второй:
C1: 20694
C2: 1843
C3: 218
C4: 168
C5: 28936
C6: 5923
C7: 2500
A: 3
B: 22
C: 6
D: 12
D1: 0
D2: 0

Откуда взялись отрицательные значения? У меня везде unsigned char/int wacko.gif
Есть одна мысль, которая требует проверки. Может действительно проблема в частоте? По-моему чтобы считать EEPROM частота на MCLK не нужна. Она нужна только для АЦП. Поправьте меня, если я не прав. В микросхеме часов (DS1388) стоит кварц 13768 (12,5пФ вместо необходимых 6пФ). Может из-за этого микросхема выдает пониженную частоту , и АЦП не хочет запускаться?
Go to the top of the page
 
+Quote Post
sls_
сообщение Aug 29 2007, 13:27
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-03-07
Пользователь №: 25 875



1. врятли, у меня одного раза хватило.
2. возможно перепутано oscout и oscin, по моему коэффициенты считываются из какой то внутренней флехи и частота там не нужна.
3. да наверно, хотя если брак то как правило вся партия целиком.
В программе не увидел ничего криминального, единственное не очень понял реализацию сброса.
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 29 2007, 14:26
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Цитата(sls_ @ Aug 29 2007, 16:27) *
возможно перепутано oscout и oscin

Это первое, что я проверил. MCLK беру со 2-го вывода RTC. Мне все-таки кажется, что у RTC не хватает нагрузочной способности. Имеет ли смысл попробовать взять частоту 32768, например, с ассинхронного таймера Меги32?
Цитата(sls_ @ Aug 29 2007, 16:27) *
единственное не очень понял реализацию сброса.

Да что тут непонятного?
Код
void fosp01Init(void)
{
  DDRD |= (1<<XCLR);      //XCLR - на выход

  PORTD &= ~(1<<XCLR);  //XCLR=0
  delay_ms(100);                //пауза 100мсек
  PORTD |= (1<<XCLR);     //XCLR=1
}

А что на счет отрицательных коэффициентов?
Цитата
Добавлено

Вместо микросхемы RTC (DS1388) использовал асинхронный таймер Меги32. Подключил кварц 32768 на TOSC1, TOSC2. Выход на MCLK взял с TOSC2(выход осциллятора). ТА ЖЕ ФИГНЯ!!! mad.gif
Go to the top of the page
 
+Quote Post
bullit
сообщение Aug 29 2007, 17:37
Сообщение #24


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Вроде код нормальный.

Цитата
void fosp01Init(void){
  DDRD |= (1<<XCLR);      //XCLR - на выход
  PORTD &= ~(1<<XCLR);  //XCLR=0
  delay_ms(100);                //пауза 100мсек
  PORTD |= (1<<XCLR);     //XCLR=1}

Может перед этим не хватает этой строчки (мало ли, забыли или закаментили):
#define XCLR PDn; // где n - номер порта для сброса АЦП FOSP

+ советую использовать встроенный в мегу асинхронный Т/С с кварцем на 32 и двумя кондерами.
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 29 2007, 17:59
Сообщение #25


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Нет, такие ошибки у меня не бывают. На счет использования таймера я уже писал...Без результатно.
Я очень разочарован... Если кому интересно, выложу свои исходники. Интересно все-таки в чем проблема: в железе или в софте.
Go to the top of the page
 
+Quote Post
bullit
сообщение Aug 30 2007, 13:56
Сообщение #26


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



Был бы очень рад исходникам. Тем более под мегу, как я понимаю.
Может что и нарою.

Удачи!
Go to the top of the page
 
+Quote Post
alux
сообщение Aug 30 2007, 14:51
Сообщение #27


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Проблема решена. 1111493779.gif Как я и предполагал, проблема была в низкой нагрузочной способности осциллятора DS1388. В принципе об этом даже было сказано в апноте AN58 DallasSemiconductor по поводу того, что нельзя подключать даже осциллограф к кварцу. Собрал отдельный кварцевый генератор 32768 Гц на инверторах (74hc04) на отдельной платке. Подал сигнал на MCLK. И все Заработало!!!
Всем спасибо. yeah.gif
PS. Нужно было ставить DS1338. У него есть генераторный выход. Да и дешевле раза в 1,5...2. Проглядел.
Go to the top of the page
 
+Quote Post
alux
сообщение Feb 2 2008, 09:05
Сообщение #28


Знающий
****

Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447



Проблема решена частично. Датчик заработал. Но выдает завышенное атмосферное давление. 1004 мм. рт. ст. Хотя рядом стоит еще один цифровой датчик давления ASDX-DO, который показывает 730 мм.рт.ст. Что совпадает с официальным прогнозом в моем регионе. Температуру FOSP01A меряет вроде нормально.
В формуле ошибки нет. По крайней мере проверял подстановкой значений из примера даташита FOSP01A.
Пробовал использовать пример кода для HP03 аналог(замена) FOSP01. Результат тот же (завышенный). Выкладываю исходники. Может кто и найдет ошибку. Хотя сто раз перепроверял...
Код
#define fospEEPROM_ADR  0xa0    // EEPROM device address
#define fospADC_ADR     0xee    // ADC device address
#define PRESSURE        0xf0
#define TEMPERATURE     0xe8
#define mm_rt_st        0.7500638    // мм. рт. ст. (@ 0 гр. C)
//#############################################################################
// Инициализация FOSP01-A
//_____________________________________________________________________________
void fosp01Init(void)
{
  port &= ~(1<<XCLR);   //Сброс FOSP01-A
  __delay_cycles(1000);
  port |= (1<<XCLR);
  __delay_cycles(1000);
  port &= ~(1<<XCLR);
  __delay_cycles(1000);

  fosp01RxCoeff();

// с1=20694;
// c2=1843;
// c3=218;
// c4=168;
// c5=28936;
// c6=5923;
// a=3;
// b=22;
// c=6;
// d=12;
}

//#############################################################################
// Чтение калибровочных коэффициентов из EEPROM (FOSP01-A)
//_____________________________________________________________________________
void fosp01RxCoeff(void)
{
  unsigned char ret, HiTemp, LowTemp;

  ret = i2c_start(fospEEPROM_ADR|W);    // EEPROM write address 0xA0
  
  if(ret)
  {
    // failed to issue start condition, possibly no device found
    i2c_stop();
  }  
  else
  {
    i2c_write(16);                       // EEPROM coefficient address
    i2c_rep_start(fospEEPROM_ADR|R);    // EEPROM read address 0xA1
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);              //Считываем коэффициенты
    c1 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 16:17
        
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);
    c2 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 18:19
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);    
    c3 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 20:21
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);    
    c4 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 22:23
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);    
    c5 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 24:25
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);    
    c6 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 26:27
    
    HiTemp=i2c_read(ACK);        
    LowTemp=i2c_read(ACK);    
    c7 = (((unsigned int)HiTemp) << 8) + LowTemp;  // 28:29
    
    a = i2c_read(ACK);    // 30
    b = i2c_read(ACK);    // 31
    c = i2c_read(ACK);    // 32
    d = i2c_read(NACK);   // 33  last byte must NACK

    i2c_stop();
  }
}

//#############################################################################
// Чтение данных АЦП (FOSP01-A)
//_____________________________________________________________________________
unsigned int fosp01RxValue(unsigned char n)
{
  unsigned char ret, HighTemp, LowTemp;
  unsigned int temp;
  
  ret=i2c_start(fospADC_ADR|W);   // ADC device write address 0xEE
    
  if(ret)
  {
    // failed to issue start condition, possibly no device found
    i2c_stop();
  }  
  else
  {
    i2c_write(0xff);
    i2c_write(n);                 // Pressure(0xF0), Temperature(0xE8)
    i2c_stop();
  
    delay_ms(50);
  
    i2c_start(fospADC_ADR|W);     // ADC device write address 0xEE
    i2c_write(0xfd);
  
    i2c_rep_start(fospADC_ADR|R); // ADC device read address 0xEF
    
    HighTemp=i2c_read(ACK);        
    LowTemp=i2c_read(NACK);  
    temp = (((unsigned int)HighTemp)<<8) + LowTemp;
  
    i2c_stop();
  }

  return temp;
}

//#############################################################################
// Вычисление температуры и атмосферного давления
// с учетом калибровочных коэффициентов
//   input  -> D1,D2,C1---C7,A,B,C,D
//  output -> Press, unit: 0.01 hpa
//                Temp, unit: 0.1 C
//_____________________________________________________________________________
void PressureTemperatureMeasure(void)
{
  double dUT;
  double off, sens, x;        // offset, sensivity
  
  unsigned long SumValueAD=0;
  
  port |= (1<<XCLR);
  __delay_cycles(1000);  

  d1 = fosp01RxValue(PRESSURE);      // measured pressure
  SumValueAD += d1;
  d1 = fosp01RxValue(PRESSURE);      
  SumValueAD += d1;
  d1 = fosp01RxValue(PRESSURE);    
  SumValueAD += d1;
  d1 = fosp01RxValue(PRESSURE);    
  SumValueAD += d1;
  d1 = SumValueAD >>2;
  d2 = fosp01RxValue(TEMPERATURE);   // measured temperature

// d1=40506;
// d2=29136;

  port &= ~(1<<XCLR);
  
  printf_P("\n\r Измеренное абсолютное давление D1:   %u", d1);
  printf_P("\n\r Измеренная температура возле датчика D2:   %u", d2);

  if(d2 >= c5) dUT = (d2-c5) - (((d2-c5)/pow(2,7))*((d2-c5)/pow(2,7))*a)/pow(2,c);  
  else         dUT = ((double)d2-c5) - (((double)d2-c5)/pow(2,7))*(((double)d2-c5)/pow(2,7))*b/pow(2,c);

  t = (250 + ((dUT*c6)/pow(2,16)) - dUT/pow(2,d))/10; // calculate final temperature value ( C)
  
  //OFF = (C2+(C4-1024)*DUT/Get2_x(14))*4;
  off = (c2+(c4-1024)*dUT/pow(2,14))*4;     // calculate offset
  
  //SENS = C1+C3*DUT/Get2_x(10);
  sens = c1+(c3*dUT)/pow(2,10);             // calculate sensivity
  
  //X = SENS*(D1-7168)/Get2_x(14)-OFF;
  x = (sens*(d1-7168))/pow(2,14)-off;
  
  //Press = X*100/Get2_x(5)+C7*10;
  p = ((x*100/pow(2,5)+c7*10)/100)*mm_rt_st;    // calculate final pressure value (мм. рт. ст.)

  printf_P("\n\r Пересчитанное абсолютное давление : %f, мм. рт. ст.", p);
  printf_P("\n\r Пересчитанная температура возле датчика: %f, C", t);
}

//=============================================================================
void calculate(void)
{
  delay_ms(50);
  
  fosp01RxCoeff();
  
  while(1)
  {
     PressureTemperatureMeasure();
     delay_ms(1000);
  }
}

Я все же склоняюсь к мысли, что проблема в самих датчиках (FOSP01A). Не зря же их заменили на HP03.
Go to the top of the page
 
+Quote Post
sls_
сообщение Feb 4 2008, 09:41
Сообщение #29


Участник
*

Группа: Участник
Сообщений: 27
Регистрация: 4-03-07
Пользователь №: 25 875



я считал так:

d1 = FOSP01RxValue(0xf0);
d2 = FOSP01RxValue(0xe8);
if(d2 >= c5) dut = d2-c5 - ((d2-c5)/128)*((d2-c5)/128)*a/pow(2,c);
else dut = d2-c5 - ((d2-c5)/128)*((d2-c5)/128)*b/pow(2,c);
t = 250+dut*c6/65536;
Ts.tek=t;//numbers(35,1,1,t);
off = (c2+(c4-1024)*dut/16384)*4;
sens = c1+c3*dut/1024;
x = sens*(d1-7168)/16384-off;
p = x*10/32+c7;
p = p*75006/100000;
Da.tek=p/10;//numbers(35,5,0,p/10);

в свое время пробовал три варианта из разных даташитов, остановился на этом, почему непомню, попробуй может поможет.
Go to the top of the page
 
+Quote Post
bullit
сообщение Mar 22 2008, 20:13
Сообщение #30


пуля
****

Группа: Свой
Сообщений: 674
Регистрация: 10-05-06
Из: Уфа
Пользователь №: 16 959



А что если его тактировать с выхода Меги(другого МК), но не с осцилятора напрямую, а с выхода таймера? Т.е. дать ему не синусойду, а меандр? Он ведь будет тактироваться?

Или может буфер на операционике собрать OPA364 ?

И как решились проблемы с расчётом давления?
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 07:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01491 секунд с 7
ELECTRONIX ©2004-2016