Регулятор давления.

varvik85
Offline
Зарегистрирован: 28.01.2013

Здравствуйте уважаемые знатоки и ветераны ARDUINO.Появилась очень большая необходимость в регуляторе давления насосной станции.От регулятора требуется выводить показания давления на дисплей, а так же возможность устанавливать нужное значение давления(которое так же отображалось бы на дисплее) дойдя до которого насос бы отключался.Планируемый датчик давления MPX2010DP.Подумал использовать переключатель "нижний предел давления" "верхний предел" и кнопки вверх вниз для регулировки выбранного значения.значение с датчика в 10МВ будт соответствовать 0,1МПа предел измерения 5MПа.Хотелось бы чтоб в верхней строке дисплея выводилось измеряемое давление а в нижней строке выводилосись "нижний предел" включения и "верхний предел"отключения насоса.Начал изучать всевозможные туториалы и статьи,но многое мне не понятно.Попробовал написать начало программы,если что то не так пожалуйста подправьте.

#include <LiquidCrystal.h>
#define SW_VERH 8 // Переключатель верхний придел давления
#define SW_NIZ 9 // Переключатель нижний предел давления
#define BUT_UP 18//Кнопка вверх
#define BUT_DOWN 19 // Кнопка вниз
#define RLY_COMPRESSOR 14 // Реле компрессора

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

// variables for input pin and control LED
int analogInput = 1;
float vout = 0.0;
float vin = 0.0;
float R1 = 50000.0; // сопротивления пожалуй оставлю
float R2 = 4400.0; // буду менять эти значения когда буду настраивать
int value = 0; // переменная для хнанения значений если можно прокоментируйте зачем она нужна
//устанавливаем пины
pinMode(analogInput, INPUT);
pinMode(SW_VERH, INPUT);
pinMode(SW_NIZ, INPUT);
pinMode(BUT_UP, INPUT);
pinMode(BUT_DOWN, INPUT);
pinMode(RLY_COMPRESSOR, OUTPUT)
// Инициализируем дисплей
lcd.begin(16, 2);
lcd.print("Vin=");
}
void loop(){
// считываем аналоговый вход
value = analogRead(analogInput);

vout = (value * 5.0) / 1024.0;
vin = vout / (R2/(R1+R2));

// выводим результат на дисплей
lcd.setCursor(4, 0);
lcd.print(DAVLENIYE);
lcd.print("MPa");

Вот что получилось.Дальше я не знаю как мне выводить на дисплей значения с кнопок и переключателя,допустим переключатель стоит в положонии "нижний предел регулировки давления" и нажатием на кнопки вверх и вниз прибавлять или отнимать по 0,5 MПа.Как после привязать выход реле к этому всему???Помогите пожалуйста,буду очень присзнателен!

maksim
Offline
Зарегистрирован: 12.02.2012
Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Сначала словами (без мата) пишется сценарий работы железки. Например:

Включение

- читаем конфигурацию и настройки.

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

- по результату - принимаем какое-то управляющее решение.

- отслеживаем результат управляющего решения.

Дальше рисуем возможные сценарии катаклизмов:

- что делать, если насос включили, а давление - не растет?

- наличие воды со стороны всасывания, я так понимаю, проблемой не является?

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

maksim
Offline
Зарегистрирован: 12.02.2012

К сожалению, вы очень мало изучили, что бы вам можно было чем-то помочь. Нет конкретных вопросов. Начните изучать отдельные примеры работы с кнопками, с дисплеем, с датчиком и т.д. и т.п. Воспользуйтесь поиском по сайту.
Вот, например, тема о кнопках

varvik85
Offline
Зарегистрирован: 28.01.2013

Давайте распишу подробнее.

устройство включается и опрашивается датчик давления(подключенный к аналоговому входу) который при увеличении давления на 0,1МПа увеличивает напряжение на 10МВ которое измеряется программой и переводится в МПа и вывоится на дисплей в верхней строке

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

если значение с датчика меньше или равно минимальному значению например 1МПа то насос включается далее как только наберет верхнее значение например 2МПа выключается,если при включении давление больше или равно верхниму пределу насос естественно не включается.

если при включении давление больше заданного на 0,5 МПа выводить сигнал об переизбытке давления

если при включении насоса давление не начнет нарастать в течении некоторого времини (около 20сек/МПа) выводиь соообщение о нарушении работы насоса.

регулировка порога срабатывания переключив тумблер в режим "включение" и "выключение" под которыми я подрузомеваю неижние и верхние пороги включения/отключения насоса и кнопками вверх и вниз изменять эти значения. которые занесутся в память и будут хранится там даже после отключения устройства.

 

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

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

 

varvik85
Offline
Зарегистрирован: 28.01.2013

maksim про кнопки я  читал конечно, спасибо за интересную ссылку,да много полезного.Но я по прежнему не знаю как при нажатии кнопки например вниз отнимать значения по 0,5МПа а кнопкой вверх прибавлять выводить это все на жки да еще и реле заставить сравнивать между этим значением и значением с датчика давления

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Я бы предложил решать задачу по частям:

1. вывод произвольных буковок на экран.

2. вывод измеренных данных с датчика давления на экран.

3. сохранение данных в eeprom, с последующим чтением их при запуске.

После этого, при работающем датчике и ручном управлении, пишем условия и моделируем включение насоса светодиодом на одном из пинов.

Дальше уже можно говорить об автоматизации всего этого в одной программе.

 

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

Но я по прежнему не знаю как при нажатии кнопки например вниз отнимать значения по 0,5МПа а кнопкой вверх прибавлять

Зачем Вам лишние преобразования? Делайте сразу нажатие кнопки в милливольтах датчика. :) Есть событие: нажали кнопку (там еще будут нюансы с фронтами, борьбой с дребезгом и т.п.) - по этому событию минусуем текущую уставку регулятора на 30 милливольт, например, и записываем это значение в eeprom. Или не записываем, учитывая тот факт, что количество циклов у eeprom, находящегося внутри самой atmega - достаточно невелико.

varvik85
Offline
Зарегистрирован: 28.01.2013

по дребезгу думаю использовать триггер и RC цепочку,как осуществлять запись и чтение??? можно пример???количество циклов не велико?куда тогда скидывать значения для хранения? можно пример считываия значения кнопки которое складывалось при каждом нажатии и выводилоь на дисплей например,и пример вычитания этого значения при нажатии с вывоом на дисплей

varvik85
Offline
Зарегистрирован: 28.01.2013

Andrey_Y_O

да это Вы верно подметили!нет ли у Вас ссылок на подобные статьи?

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

да это Вы верно подметили!нет ли у Вас ссылок на подобные статьи?

У меня пока только свой малюсенький проект: http://inet-deal.mpa.ru/articles/arduino-002.html

Да и зачем тут статьи: начинайте с датчика... Когда победите прыгающие значения - как раз и опыт по изменению количества циклов будет. Кнопок у меня нет, и не планируется: зачем мне автоматика с кнопками? :)

varvik85
Offline
Зарегистрирован: 28.01.2013

ох у Вас там интеренет шильд,для меня это все пока мега сложно,что касается датчика так он просто изменяет напряжение от приложенного давления,ардуино играет роль вольтметра но вот с такими наворотами в виде реле и кнопок)

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

что касается датчика так он просто изменяет напряжение от приложенного давления,ардуино играет роль вольтметра но вот с такими наворотами в виде реле и кнопок)

Вот именно поэтому я Вам и говорю: "начните с датчика", который кажется самым простым. На самом деле - аналоговый датчик, тем более давление при вибрации от работающего насоса... Вобщем, на мой взгляд, у Вас там будет с чем развлечься... Все остальное - гораздо проще.

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

varvik85
Offline
Зарегистрирован: 28.01.2013

нет для меня программирование самое сложное))) датчик в связке с операционным уселителем и ардуино будет установлен не на самом насосе а отдельно,вибраций не будет,датчик я уже проверил,меняет напряжение от 0 до 5 вольт,вернее я его так настроил,10Мв = 0,01 МПа предел насоса 5МПа,как раз то что нужно.та часть программы что приведена выше и есть немного измененный вольтметр

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

нет для меня программирование самое сложное))) датчик в связке с операционным уселителем и ардуино будет установлен не на самом насосе а отдельно,вибраций не будет,датчик я уже проверил,меняет напряжение от 0 до 5 вольт,вернее я его так настроил,10Мв = 0,01 МПа предел насоса 5МПа,как раз то что нужно.та часть программы что приведена выше и есть немного измененный вольтметр

То есть у Вас код, приведенный в первом сообщении, работает на живом датчике, установленном на трубопроводе и значения датчика - не прыгают?

Тогда, наверное, следует завернуть операцию опроса датчика в цикл из millis(), чтобы читать их раз в N секунд.

Я бы сначала сделал отдельную функцию и вынес константу делителя в setup(), чтобы не вычислять ее каждый раз при обращении:

float getSensorValue ( int sensorPin )
{
	// считываем аналоговый вход
	value = analogRead(analogInput);
	vout = (value * 5.0) / 1024.0;
        // KONS1 = (R2/(R1+R2)); <- задаем в setup()
	vin = vout / KONS1 
}

TIME_OFF_SENSOR задается в константах до setup()

const uint16_t TIME_OFF_SENSOR = 20000;

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

/* Collect sensor data */ 
if( millis() - old_millis > TIME_OFF_SENSOR )
  { 
  // запомнили текущее время 
  old_millis = millis(); 
  // вызвали функцию опроса датчика 
  sensor_0_Value = getSensorValue(sensorPin0); 
  }

 

varvik85
Offline
Зарегистрирован: 28.01.2013

спасибо! я если честно не совсем понял зачем это нужно,но чуть позже все проанализирую,хочу Вас попросить привести пример программы которая позволяла бы опрашивать кнопки и при каждом нажатии складывать или отнимать значение с выводом на дисплей

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

я если честно не совсем понял зачем это нужно,

Цикл loop() работает в соответствии с тактами процессора (например 16 мегагерц). Нам так быстро получать данные не надо, да и кроме того, чтобы измерять значение датчика, мы еще много чего хотим сделать. Поэтому мы делаем цикл, который запускает опрос датчика через интервал времени примерно в 20 секунд, а остальное время крутится впустую, или делает другие операции.

varvik85 пишет:

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

http://arduino.ru/forum/programmirovanie/rabota-s-knopkami-v-pomoshch-novichku - дак вот тут по кнопкам есть

	     if(digitalRead(14)==HIGH&&flag==0)//если кнопка нажата  
	     // и перемення flag равна 0 , то ...
	     {
	           
	         
	       flag=1;
	        //это нужно для того что бы с каждым нажатием кнопки
	        //происходило только одно действие
	        // плюс защита от "дребезга"  100%

             // здесь пишем: что еще сделать по нажатой кнопке
             // например добавляем к уставке регулятора 50 милливольт
             pressure_0_Value = pressure_0_Value + 50;

	        
	     } 

куча примеров...

Текущие значения на экран можно выводить постоянно в цикле loop() с delay(5) например, или в цикле опроса датчика, тогда они будут изменяться тоже раз в 20 секунд.

varvik85
Offline
Зарегистрирован: 28.01.2013

Спасибо!Мне правда требуется время чтобы это все усвоить,теперь я на верном пути благодоря Вам!

varvik85
Offline
Зарегистрирован: 28.01.2013

Как с Вами связаться?

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

varvik85 пишет:

Как с Вами связаться?

Дак в форуме и связывайтесь. :) Не я, так кто-нибудь другой подскажет. За исполнение частных заказов я не берусь.

sir_kimas
Offline
Зарегистрирован: 01.08.2016

Чтонибудь получилось?

 

Ardfun
Offline
Зарегистрирован: 22.05.2016

Здравствуйте, интересует тема измерения скорости изменения давления

сейчас я использую для измерения 

такой простой код чтоб выводить скорость изменение давления на экран раз в минуту:

  void loop() {
dps.getAltitude(&Pressure0);
delay(60000);
  dps.getAltitude(&Pressure);

 PresSpeed =(( Pressure - Pressure0)/100); (давление в гектопаскалях)

myGLCD.setFont(SmallFont);

myGLCD.printNumF(PresSpeed, 0, 25, 0);

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

то вопрос как подставить milis вместо delay код я так понял код будет посложнее, подскажите куда копать чтоб это реализовать.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Это вам надо? 

knok отправляется раз в 0.5 сек.

uint8_t non_stop_program(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
void setup() {
  Serial.begin(9600);
}
void loop() {
  if (non_stop_program(500))  Serial.println("knok");
  // здесь всталяете программу
}

 

Ardfun
Offline
Зарегистрирован: 22.05.2016

Не совсем понял кода

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Ardfun пишет:

Не совсем понял кода

а вы его загружали?

Ardfun
Offline
Зарегистрирован: 22.05.2016

qwone пишет:

Ardfun пишет:

Не совсем понял кода

а вы его загружали?

Не загружал, так как не могу пока связать что куда вписывать я только учусь:) так что если можетеп подскажите последовательность )

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Гарантировать не могу . Потому что не знаю работает ли ваш код.

uint8_t non_stop_program(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
void setup() {

}
void loop() {
  if (non_stop_program(60000)) { // вот раз в минуту и будет отправлять показание. А цикл loop() будет крутится как обычно
     dps.getAltitude(&Pressure);
     PresSpeed =(( Pressure - Pressure0)/100); //(давление в гектопаскалях)
     myGLCD.setFont(SmallFont);
     myGLCD.printNumF(PresSpeed, 0, 25, 0);
  }
}

 

Ardfun
Offline
Зарегистрирован: 22.05.2016

Что то не увязывается с моим кодом, а где вы дели Pressure0 в вычеслениях ведь логика должна быть такой чио программма берет давление в данный отрезок времени и называем его Pressure0 через минуту замеряет Pressure и формула PresSpeed =(( Pressure - Pressure0)/100); вычисляет скорость изменения гектопаскалей в минуту

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

 Тогда скорее всего так. 

float pressure_speed() {  //(давление в гектопаскалях)
 static float Pressure0;
 float PresSpeed;
 dps.getAltitude(&Pressure);
 PresSpeed =( Pressure - Pressure0)/100;
 Pressure0 = Pressure;
 return PresSpeed;
// = ядро вычислительное 
 uint8_t non_stop_program(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
void setup() {

}
void loop() {
  if (non_stop_program(60000)) { // вот раз в минуту и будет отправлять показание. А цикл loop() будет крутится как обычно
     PresSpeed = pressure_speed();
     myGLCD.setFont(SmallFont);
     myGLCD.printNumF(PresSpeed, 0, 25, 0);
  }
}

Ardfun
Offline
Зарегистрирован: 22.05.2016

пишит такую ошибку error: 'non_stop_program' cannot be used as a function

я что то не то делаю наверное ?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скорее всего 

//float pressure_speed() {  //(давление в гектопаскалях)
// static float Pressure0;
// float PresSpeed;
// dps.getAltitude(&Pressure);
// PresSpeed =( Pressure - Pressure0)/100;
// Pressure0 = Pressure;
// return PresSpeed;
//// = ядро вычислительное 
 uint8_t non_stop_program(uint16_t span) {
  static uint32_t future = 0;
  if (millis()<future) return 0;
  future += span;
  return 1;
}
void setup() {

}
void loop() {
  if (non_stop_program(60000)) { // вот раз в минуту и будет отправлять показание. А цикл loop() будет крутится как обычно
//     PresSpeed = pressure_speed();
//     myGLCD.setFont(SmallFont);
//     myGLCD.printNumF(PresSpeed, 0, 25, 0);
  }
}

Вот так у меня компилится без проблем. А полностью у меня не сможет работать. Так как не весь код. Да и изделия вашего у меня нет

Ardfun
Offline
Зарегистрирован: 22.05.2016

Благодарю, буду разбираться :)

Ardfun
Offline
Зарегистрирован: 22.05.2016

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

  digitalWrite(13, HIGH);   // зажигаем светодиод
  delay(1000);              // ждем секунду
  digitalWrite(13, LOW);    // выключаем светодиод

как тут дилей  заменить на милис, я не совсем логику и синтаксис понимаю чтоб добрать толку

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
const int out_pin=13;// нога LED
uint8_t stat = 0;

void setup() {
  pinMode(out_pin, OUTPUT);
  digitalWrite(out_pin, stat);
}

void loop() {
  static uint32_t MILLIS ;
  MILLIS = millis() ;
  static uint32_t future1 = 0 ;
  if (MILLIS>=future1) {
  future1 = MILLIS + 1000 ; // вычислит. поток 1 действует раз в 1000 миллисекунд.
    // код потока 1
  stat =!stat;
  digitalWrite(out_pin, stat);   
  }
}
 

 

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

qwone, вы уверены?

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Gippopotam пишет:

qwone, вы уверены?

В чем я уверен?

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

qwone пишет:

Gippopotam пишет:

qwone, вы уверены?

В чем я уверен?

Это был вопрос. С подвохом. Типа ради трллинга.

Tolchoks
Offline
Зарегистрирован: 27.05.2016

varvik85 пишет:

Давайте распишу подробнее.

устройство включается и опрашивается датчик давления(подключенный к аналоговому входу) который при увеличении давления на 0,1МПа увеличивает напряжение на 10МВ которое измеряется программой и переводится в МПа и вывоится на дисплей в верхней строке

Регуляторы давления газа от СтримГаз.

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

если значение с датчика меньше или равно минимальному значению например 1МПа то насос включается далее как только наберет верхнее значение например 2МПа выключается,если при включении давление больше или равно верхниму пределу насос естественно не включается.

если при включении давление больше заданного на 0,5 МПа выводить сигнал об переизбытке давления

если при включении насоса давление не начнет нарастать в течении некоторого времини (около 20сек/МПа) выводиь соообщение о нарушении работы насоса.

регулировка порога срабатывания переключив тумблер в режим "включение" и "выключение" под которыми я подрузомеваю неижние и верхние пороги включения/отключения насоса и кнопками вверх и вниз изменять эти значения. которые занесутся в память и будут хранится там даже после отключения устройства.

 

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

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

 

 

а с таким работали регулятором давления газа:

регуляторы давления газа