Ёмкостной датчик

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

Добрый день! Гуру, помогите пожалуйста чайнику!

Задачка выглядела примерно так: 

Ёмкостной датчик, это труба в трубе. Датчик включен в качестве конденсатора в генератор насчётчике  ВИ-1. При наполнении зазора между трубами, частота генерации меняется. Этот узел работает надёжно и стабильно. Дальше - Ардуина. Поскольку, тему я знаю плохо, и с подключением индикатора мне не справиться, то в качестве индикатора решил использовать готовый цифровой вольтметр. Ардуина же должна выдавать аналоговый сигнал по выходу PWM с соответствующим уровнем, который подключен к этому вольтметру. 

Сразу раскрою карты: я - полнейший дилетант. Ардуину освоил на уровне мигания диодиком, шевеления сервами и прочими несложными операциями. После долгих неудачных попыток сделать надёжный и стабильный блок частотомера, нашёл готовый в сети. Ссылку потерял, там шла речь про велоспидометр.

К готовому блоку программы этого велоспидометра я добавил с десяток своих строк (почти все они в "void loop()". В общем, после некоторой отладки всё заработало. Всё супер, и как мечталось, если бы одна проблема:

Скетч не запускается при подаче питания. Чтобы он запустился, надо подключить ардуину к компьютеру, войти в "монитор порта", дать команду "run@ или "print", тогда всё начинает работать.

Скорее всего, так сделан блок частотомера, который я дёрнул из сети. Для меня он неимоверно сложен, и логики его работы я не понимаю. 

Просьба к специалистам: проверьте пожалуйста скетч на предмет незапускаемости без подключения к компьютеру:

float FH=4601; //пустой бак, саммая высокая частота, PWM=0
float FLN=2300; //полный бак (50л), самая низкая частота, PWM=255
 
 
volatile unsigned int int_tic=0;
 
volatile unsigned long tic;
 
 
 
void setup(){
 
Serial.begin(9600);
pinMode (6,OUTPUT);
 
pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
 
TCCR2A=1<<WGM21; //CTC mode
 
TIMSK2=1<<OCIE2A; OCR2A=124 ;//прерывание каждые 8мс
 
TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20); //делитель 1024
 
TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
 
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
 
}
 
 
 
ISR (TIMER1_OVF_vect){ int_tic++; }
 
 
 
ISR (TIMER2_COMPA_vect){
 
  static byte n=1;
 
  if (n==125){
 
           tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
 
           int_tic=0;
 
           TCNT1 = 0; n=0;
 
           }
 
      n++;
 
}
 
 
 
void loop(){
  
float FL=FLN-1024+analogRead(5)*2;
 
delay(500);
float PW=(255*(tic-FH))/(FL-FH);
if(0>PW) { //получился меньше нуля
    PW=0;
   }
   
   if(PW>255) {   //получился больше 255
   PW=255;
 } 
   
   
analogWrite(6,PW);
Serial.println("____________");
Serial.println(tic);
Serial.println(FL);
Serial.println(analogRead(5));
Serial.println(PW);
}
 
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Илья МГУ пишет:

Ардуина же должна выдавать аналоговый сигнал по выходу PWM с соответствующим уровнем, который подключен к этому вольтметру. 

Кому это, интересно, она так задолжала? PWM выдаёт, а вот аналоговый сигнал с каким-бы то ни было уровнем, отличным от HIGH и LOW она никому не должна.

Илья МГУ пишет:

Чтобы он запустился, надо подключить ардуину к компьютеру, войти в "монитор порта", дать команду "run@ или "print", тогда всё начинает работать.

В том коде, что Вы привели нет ни одной операции чтения чего-либо из порта. Так что Вы можете подавать команду "run@", "print" или даже "lyaba-zyaba" сколько угодно, программа всё равно не читает никаких команд. Так что дело не в этом.

И пожалуйста, соблюдайте правила форума. http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

 

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

ЕвгенийП пишет:
Кому это, интересно, она так задолжала? PWM выдаёт, а вот аналоговый сигнал с каким-бы то ни было уровнем, отличным от HIGH и LOW она никому не должна. 

И пожалуйста, соблюдайте правила форума. http://arduino.ru/forum/obshchii/vstavka-programmnogo-koda-v-temukommentarii

 

Аналоговый сигнал 0-5В получается из-за ёмкости, которая стоит на входе вольтметра. Это работает. Меня вообще всё устраивает, кроме того, что скетч не запускается без компьютера.

О правилах не знал, буду соблюдать. Как редактировать первое сообщение, не нашёл.

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

ЕвгенийП пишет:
В том коде, что Вы привели нет ни одной операции чтения чего-либо из порта. Так что Вы можете подавать команду "run@", "print" или даже "lyaba-zyaba" сколько угодно, программа всё равно не читает никаких команд. Так что дело не в этом.

В чём может быть причина? В дефекте загрузчика, или сам камень битый?

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

Илья МГУ пишет:

В чём может быть причина? В дефекте загрузчика, или сам камень битый?

Опубликуйте код номрально. Смотреть на него так очень трудно и теб более обсуждать.

Для этого не обязательно править первое сообщение, отдельным сообщением опубликуйте.

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

ЕвгенийП пишет:
Для этого не обязательно править первое сообщение, отдельным сообщением опубликуйте.

Ок.

float FH=4601; //пустой бак, саммая высокая частота, PWM=0
float FLN=2300; //полный бак (50л), самая низкая частота, PWM=255


volatile unsigned int int_tic=0;

volatile unsigned long tic;

 

void setup(){

Serial.begin(9600);
pinMode (6,OUTPUT);

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)

TCCR2A=1<<WGM21; //CTC mode

TIMSK2=1<<OCIE2A; OCR2A=124 ;//прерывание каждые 8мс

TCCR2B=(1<<CS22)|(1<<CS21)|(1<<CS20); //делитель 1024

TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению

TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1

}

 

ISR (TIMER1_OVF_vect){ int_tic++; }

 

ISR (TIMER2_COMPA_vect){

  static byte n=1;

  if (n==125){

           tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало

           int_tic=0;

           TCNT1 = 0; n=0;

           }

      n++;

}

 

void loop(){
  
float FL=FLN-1024+analogRead(5)*2;

delay(500);
float PW=(255*(tic-FH))/(FL-FH);
if(0>PW) { //получился меньше нуля
    PW=0;
   }
   
   if(PW>255) {   //получился больше 255
   PW=255;
 } 
   
   
analogWrite(6,PW);
Serial.println("____________");
Serial.println(tic);
Serial.println(FL);
Serial.println(analogRead(5));
Serial.println(PW);
}

 

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

Пояснение: аналоговый вход А5, это для подстройки. На нём делитель с подстроечником, чтобы можно было выставить нужную цифру при полном баке. Так надо, поскольку диэлектрическая проницаемость сжиженного газа бывает разной. Установка на "ноль" при пустом баке делается один раз, правкой кода (1-я строка). Все "принты" в конце - это чисто для настройки, при работе они не нужны. Конечная цель - строка "analogWrite(6,PW);", больше ничего не требуется.

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

В этом коде я не вижу причин почему бы он начинал работать только после плясок с бубнами вокруг сериала. Ищите причины в питании и вообще в схеме.

14-ая строка не нужна. PWM не нуждается в конфигурации порта. Уберите от греха подальше.

16-ая строка непонятна. 5-ый цифровой пин, кажется нигде не используется. Или я что-топропустил? Если не используется, то тоже убирайте.

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

14-я строка, понял.

16-я строка: 5-й цифровой пин, это как раз входной сигнал от генератора. Достался от автора базового кода (велоспидометр). Я его и использую.

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

Илья МГУ пишет:

14-я строка, понял.

16-я строка: 5-й цифровой пин, это как раз входной сигнал от генератора. Достался от автора базового кода (велоспидометр). Я его и использую.

В каком месте Вы его используете? Я не нашёл. Номер строки?

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

Ага, дошло, Вы его в строке 26 используете, сорри.

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

Евгений, спасибо! Вы меня успокоили, код не виноват. Менять в схеме мне особо нечего, отладка происходит на плате Ардуино Уно. Проще всего попробовать заменить контроллер.

Илья МГУ
Offline
Зарегистрирован: 18.03.2014

Вопрос снят, дело в контроллере. После замены стал запускаться без сериала. Спасибо!