0 / 0 / 0
Регистрация: 10.02.2017
Сообщений: 11
1

Arduino. Управление двигателем от датчика давления

27.02.2018, 22:35. Показов 4196. Ответов 9

Привет . В просторах интернета нашел скетч - управление насосом от датчика давления на 1 реле .Переделал скетч на 2 реле. Опробовал на Arduino Uno - подключил дисплей 1602 , в место датчика давления подключил на вход А0 - регулиромое напряжение 5 вольт - через резистор 1 ком . Кнопки не подключал и без них работает.
Расскажу кратко работу программы : на дисплеи две строчки вывода информации , первая строка( левое число) показывает - минимальное давление ( установленное 1.00) , в середине давление - от датчика давления и с права установленное максимальное давление ( 2.00 ) . А нижняя строка показывает уровень давления ( шкала из квадратиков ) пределы от минимума до максимума , в скетче 1.00 атмосфер до 2.00 атмосфер - если давление на входе А0 ниже 1.00 ( и выше 2.00 ) - происходит мигание всего дисплея - хотелось бы переделать скетч чтоб этого мигания не было . Может кто подскажет ? И шкалу растянуть от 0.70 до 2.30 давление .
Работа реле в начальный момент - если давление 1.50 -реле 1 и 2 выключены , давление падает до 1.00 реле 1 включается ( у меня пока светодиод ,он мигает ) при повышении давления светодиод гаснет. При увеличении давления - алгоритм работы такой же ( реле 2 ). Работу реле тоже надо бы поменять - отказаться от delay применить millis . Нужный алгоритм работы реле 2 секунды включено и 20 секунд стоит для реле 1 и 2 , но чтоб основная программа не тормозилась.
Ниже скетч , схему подключения если надо закину на форум. Может кто подскажет ?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
#include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    
    //define zone---------------
    #define b1 6        //left LOW
    #define b2 5        //right HIGH
    #define ledG 9      //green led
    #define ledR 8      //red led
    #define ledY 7      //yellow led
    #define relay_1 2  //relay
        #define relay_2 3 
    #define sensor A0
    #define dV 0.004    //5/1023 - each 5V via analog signal
    #define PRESSURE_CORRECTION 0.2 //sensor correction
    #define PMIN 1.0   //min for LOW level
    #define PMAX 2.0    //max for HIGH level 
    #define MAX_LCD_WIDTH 16
    
    //-----------------------------
    
    //init libs zone--------------
    LiquidCrystal_I2C lcd(0x3f, 16, 2); // Устанавливаем дисплей
    //-----------------------------
    
    bool b1Status = false;
    bool b2Status = false;
    bool working = false;
    bool SYSTEM_ERROR = false;
    uint8_t addr = 0;
    unsigned long current_time = 0;
    unsigned long old_time = 0;
    unsigned long old_time2 = 0;
    unsigned long test_millis = 0;
    unsigned long prev_predict = 0; //start working
    
    //-----------------------------------
    float LOW_PRESSURE = 1.0;
    float HIGH_PRESSURE = 2.0;
    //-----------------------------------
    float CURRENT_PRESSURE = 0.0; //current pressure
    float Vout = 0.0; //current pressure
    uint16_t analogV = 0;
    //--------------------------------
    
    void setup() {
      //
      //  Serial.begin(115200);
    
      //  try to load variables from EEPPROM arduino
      LOW_PRESSURE = readDATA(0);
      if (LOW_PRESSURE == 0.0) LOW_PRESSURE = 1.00;
    
      HIGH_PRESSURE = readDATA(1);
      if (HIGH_PRESSURE == 0.0) HIGH_PRESSURE = 2.00;
    
      current_time = millis();
    
      pinMode(b1, INPUT);
      pinMode(b2, INPUT);
      pinMode(ledG, OUTPUT);
      pinMode(ledR, OUTPUT);
      pinMode(ledY, OUTPUT);
      pinMode(relay_1, OUTPUT);
          pinMode(relay_2, OUTPUT);
      pinMode(sensor, INPUT);
    
      analogV = getAnalogData();
      //Vout = (analogV * dV1) - dP;
      CURRENT_PRESSURE = getPressure(analogV);
    
      lcd.init();
      lcd.backlight();// Включаем подсветку дисплея
      lcd.clear();
      drawMenu();
      digitalWrite(ledG, LOW);
      digitalWrite(ledY, LOW);
      digitalWrite(ledR, LOW);
    
      test_millis = current_time;
    }
    void loop() {
    
      current_time = millis();
    
      //regular get sensor data
      analogV = getAnalogData();
      checkSensorHealth(analogV);
    
      //false means that we do not switch ON relay according to predict....
      //checking and geting other functions
      if (!SYSTEM_ERROR) {
        checkPressure();
        getPressure(analogV);
      }
      drawMenu();
      checkButtons(current_time);
    }
    
    //    update menu items
    void drawMenu() {
    
      delay(100);
    
      lcd.setCursor(0, 0); //x,y
      lcd.print(LOW_PRESSURE);
      lcd.setCursor(6, 0); //x,y
      lcd.print(CURRENT_PRESSURE);
      lcd.setCursor(12, 0); //x,y
      lcd.print(HIGH_PRESSURE);
          if (!SYSTEM_ERROR) {
    
        uint8_t blocks = (CURRENT_PRESSURE - LOW_PRESSURE) / ((HIGH_PRESSURE - LOW_PRESSURE) / MAX_LCD_WIDTH);
 
    
        for (uint8_t i = 15; i > blocks; i--) {
          lcd.setCursor(i, 1); //x,y
          lcd.write(254); //total hours working
        }
    
        //  draw blocks on LCD
        for (uint8_t i = 0; i < blocks - 1; i++) {
          lcd.setCursor(i, 1); //x,y
          lcd.write(255);
        }
      }
    
      else {
        lcd.setCursor(0, 1); //x,y
        lcd.print("low sensor data!");
      }
    
    }
    
    //    calc pressure from converted analog signal
    float getPressure(uint16_t analog) {
    
      Vout = (analog * dV);
      //updated formula according to:
      // 0.4 - 0bar
      // 4.5 = 12bar (1.2Mpa)
      //−12x+4.1y+4.8=0 
      //we got the following: y(pressure) = (-48/41)+((120*x)/41) | x = voltage (analog * (5/1023) = 0.004))
      CURRENT_PRESSURE = (-48/41)+((120*Vout)/41)  + PRESSURE_CORRECTION; 
    
      return CURRENT_PRESSURE;
    }
    
    //    stop relay in case if sensor through the data less that normal and default 100 from A0 pin....
    void checkSensorHealth(uint16_t analog) {
      if ((analog <= 50) or (analog >= 800) and !(SYSTEM_ERROR)) { //800~ its like ~7.5bar
        digitalWrite(ledR, HIGH);
        digitalWrite(relay_1, LOW); //switch OFF relay incase of error
        SYSTEM_ERROR = true;
      }
      if (SYSTEM_ERROR) {
        alarmErorr();
      }
    }
    
    //    alarm error
    void alarmErorr(void) {
      if (SYSTEM_ERROR) {
        digitalWrite(ledR, !digitalRead(ledR));
        if (working) {
          working = false;
          digitalWrite(ledG, LOW);
          digitalWrite(relay_1, LOW);
              digitalWrite(relay_2, LOW);
          digitalWrite(ledY, LOW); //switch ON predict LED
        }
    
      }
    }
    
    
    //    check and control main relay using predict param in case of prediction.....
    void checkPressure() {
    
      if (CURRENT_PRESSURE <= LOW_PRESSURE) {
        digitalWrite(ledG, HIGH);
        digitalWrite(relay_1, HIGH);
            digitalWrite(relay_2, LOW);
         working = true;
      }
      else if (CURRENT_PRESSURE >= HIGH_PRESSURE) {
        lcd.clear();
        digitalWrite(ledG, LOW);
        digitalWrite(relay_1, HIGH);
            digitalWrite(relay_2, LOW);
        working = false;
        digitalWrite(ledY, LOW); //switch ON predict LED
      }
    }
    
    
    
    //    getting data from the analog arduino pin - default A0 using TEST param for local testing without sensor.....
    uint16_t getAnalogData(void) {
    
      const uint8_t SIZE_BUF_ADC = 5;
      uint16_t buf_adc[SIZE_BUF_ADC], t;
      uint8_t i, j;
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
        buf_adc[i] = analogRead(sensor);
    
        //TODO: need to check and REMOVE delay
        delay(50);
        //TODO: need to check and REMOVE delay
      }
    
      //take mediana from buffer
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
    
        for (j = 0; j < SIZE_BUF_ADC - i - 1; j++) {
          if (buf_adc[j] > buf_adc[j + 1]) {
            t = buf_adc[j];
            buf_adc[j] = buf_adc[j + 1];
            buf_adc[j + 1] = t;
          }
        }
      }
    
      return buf_adc[(SIZE_BUF_ADC - 1) / 2];
    
    }
    
    
    //    check box buttons
    void checkButtons(unsigned long current_time) {
    
      if (digitalRead(b1) and ((current_time - old_time) > 200) and !b1Status) {
    
        old_time = current_time;
        b1Status = true;
    
        if (LOW_PRESSURE >= PMIN) {
          LOW_PRESSURE = 1.00;
        }
        else {
          LOW_PRESSURE += 0.1;
        }
        drawMenu();
    
    
      }
      else if (!digitalRead(b1) and b1Status) {
        b1Status = false;
        saveDATA(0, LOW_PRESSURE * 10);
      }
    
      // check the second button
    
      if (digitalRead(b2) and ((current_time - old_time2) > 200) and !b2Status) {
    
        old_time2 = current_time;
        b2Status = true;
    
        if (HIGH_PRESSURE >= PMAX) {
          HIGH_PRESSURE = 2.00;
        }
        else {
          HIGH_PRESSURE += 0.1;
        }
        drawMenu();
    
      }
      else if (!digitalRead(b2) and b2Status) {
        b2Status = false;
        saveDATA(1, (HIGH_PRESSURE + 0.1) * 10);
      }
    
    }
    
    float readDATA(uint8_t addr) {
      return (float)EEPROM.read(addr) / 10.0;
    }
    
    void saveDATA(uint8_t addr, uint8_t data) {
    
      EEPROM.write(addr, data);
    
    }
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.02.2018, 22:35
Ответы с готовыми решениями:

код для датчика давления
Не комплиирется, помогите, в чем проблема #include &lt;MPX5010x.h&gt; #include &lt;Wire.h&gt; const...

Датчик давления кнопки на arduino
Здравствуйте, уважаемые форумчане! :) Подскажите, можно ли с помощью arduino реализовать датчик...

Управление коллекторным двигателем
Пробую сделать управление движком постоянного тока. Мощность - 80...100 Вт, питание -12В,...

Управление шаговым двигателем
Всем привет! Прошу оказать посильные консультации. Подскажите, каким образом с помощью Ардуино, я...

9
348 / 282 / 144
Регистрация: 08.04.2013
Сообщений: 1,230
01.03.2018, 02:01 2
немного подправил по параметру 0,7-2,3 изменения найдете по коментариям
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    
    //define zone---------------
    #define b1 6        //left LOW
    #define b2 5        //right HIGH
    #define ledG 9      //green led
    #define ledR 8      //red led
    #define ledY 7      //yellow led
    #define relay_1 2  //relay
        #define relay_2 3 
    #define sensor A0
    #define dV 0.004    //5/1023 - each 5V via analog signal
    #define PRESSURE_CORRECTION 0.2 //sensor correction
    #define PMIN 0.7    //min for LOW level //Тут изменил
    #define PMAX 2.3    //max for HIGH level // Тут изменил
    #define MAX_LCD_WIDTH 16
    
    //-----------------------------
    
    //init libs zone--------------
    LiquidCrystal_I2C lcd(0x3f, 16, 2); // Устанавливаем дисплей
    //-----------------------------
    
    bool b1Status = false;
    bool b2Status = false;
    bool working = false;
    bool SYSTEM_ERROR = false;
    uint8_t addr = 0;
    unsigned long current_time = 0;
    unsigned long old_time = 0;
    unsigned long old_time2 = 0;
    unsigned long test_millis = 0;
    unsigned long prev_predict = 0; //start working
    
    //-----------------------------------
   // float LOW_PRESSURE = 1.0; // Тут изменил
   // float HIGH_PRESSURE = 2.0; // Тут изменил
    float LOW_PRESSURE = PMIN;
    float HIGH_PRESSURE = PMAX;
 
   
    //-----------------------------------
    float CURRENT_PRESSURE = 0.0; //current pressure
    float Vout = 0.0; //current pressure
    uint16_t analogV = 0;
    //--------------------------------
    
    void setup() {
      //
      //  Serial.begin(115200);
    
      //  try to load variables from EEPPROM arduino
      LOW_PRESSURE = readDATA(0);
     // if (LOW_PRESSURE == 0.0) LOW_PRESSURE = 1.00;  // Тут изменил
     if (LOW_PRESSURE == 0.0) LOW_PRESSURE = PMIN;
    
      HIGH_PRESSURE = readDATA(1);
     // if (HIGH_PRESSURE == 0.0) HIGH_PRESSURE = 2.00;  // Тут изменил
    if (HIGH_PRESSURE == 0.0) HIGH_PRESSURE = PMAX;
      current_time = millis();
    
      pinMode(b1, INPUT);
      pinMode(b2, INPUT);
      pinMode(ledG, OUTPUT);
      pinMode(ledR, OUTPUT);
      pinMode(ledY, OUTPUT);
      pinMode(relay_1, OUTPUT);
          pinMode(relay_2, OUTPUT);
      pinMode(sensor, INPUT);
    
      analogV = getAnalogData();
      //Vout = (analogV * dV1) - dP;
      CURRENT_PRESSURE = getPressure(analogV);
    
      lcd.init();
      lcd.backlight();// Включаем подсветку дисплея
      lcd.clear();
      drawMenu();
      digitalWrite(ledG, LOW);
      digitalWrite(ledY, LOW);
      digitalWrite(ledR, LOW);
    
      test_millis = current_time;
    }
    void loop() {
    
      current_time = millis();
    
      //regular get sensor data
      analogV = getAnalogData();
      checkSensorHealth(analogV);
    
      //false means that we do not switch ON relay according to predict....
      //checking and geting other functions
      if (!SYSTEM_ERROR) {
        checkPressure();
        getPressure(analogV);
      }
      drawMenu();
      checkButtons(current_time);
    }
    
    //    update menu items
    void drawMenu() {
    
      delay(100);
    
      lcd.setCursor(0, 0); //x,y
      lcd.print(LOW_PRESSURE);
      lcd.setCursor(6, 0); //x,y
      lcd.print(CURRENT_PRESSURE);
      lcd.setCursor(12, 0); //x,y
      lcd.print(HIGH_PRESSURE);
          if (!SYSTEM_ERROR) {
    
        uint8_t blocks = (CURRENT_PRESSURE - LOW_PRESSURE) / ((HIGH_PRESSURE - LOW_PRESSURE) / MAX_LCD_WIDTH);
 
    
        for (uint8_t i = 15; i > blocks; i--) {
          lcd.setCursor(i, 1); //x,y
          lcd.write(254); //total hours working
        }
    
        //  draw blocks on LCD
        for (uint8_t i = 0; i < blocks - 1; i++) {
          lcd.setCursor(i, 1); //x,y
          lcd.write(255);
        }
      }
    
      else {
        lcd.setCursor(0, 1); //x,y
        lcd.print("low sensor data!");
      }
    
    }
    
    //    calc pressure from converted analog signal
    float getPressure(uint16_t analog) {
    
      Vout = (analog * dV);
      //updated formula according to:
      // 0.4 - 0bar
      // 4.5 = 12bar (1.2Mpa)
      //в€’12x+4.1y+4.8=0 
      //we got the following: y(pressure) = (-48/41)+((120*x)/41) | x = voltage (analog * (5/1023) = 0.004))
      CURRENT_PRESSURE = (-48/41)+((120*Vout)/41)  + PRESSURE_CORRECTION; 
    
      return CURRENT_PRESSURE;
    }
    
    //    stop relay in case if sensor through the data less that normal and default 100 from A0 pin....
    void checkSensorHealth(uint16_t analog) {
      if ((analog <= 50) or (analog >= 800) and !(SYSTEM_ERROR)) { //800~ its like ~7.5bar
        digitalWrite(ledR, HIGH);
        digitalWrite(relay_1, LOW); //switch OFF relay incase of error
        SYSTEM_ERROR = true;
      }
      if (SYSTEM_ERROR) {
        alarmErorr();
      }
    }
    
    //    alarm error
    void alarmErorr(void) {
      if (SYSTEM_ERROR) {
        digitalWrite(ledR, !digitalRead(ledR));
        if (working) {
          working = false;
          digitalWrite(ledG, LOW);
          digitalWrite(relay_1, LOW);
              digitalWrite(relay_2, LOW);
          digitalWrite(ledY, LOW); //switch ON predict LED
        }
    
      }
    }
    
    
    //    check and control main relay using predict param in case of prediction.....
    void checkPressure() {
    
      if (CURRENT_PRESSURE <= LOW_PRESSURE) {
        digitalWrite(ledG, HIGH);
        digitalWrite(relay_1, HIGH);
            digitalWrite(relay_2, LOW);
         working = true;
      }
      else if (CURRENT_PRESSURE >= HIGH_PRESSURE) {
        lcd.clear();
        digitalWrite(ledG, LOW);
        digitalWrite(relay_1, HIGH);
            digitalWrite(relay_2, LOW);
        working = false;
        digitalWrite(ledY, LOW); //switch ON predict LED
      }
    }
    
    
    
    //    getting data from the analog arduino pin - default A0 using TEST param for local testing without sensor.....
    uint16_t getAnalogData(void) {
    
      const uint8_t SIZE_BUF_ADC = 5;
      uint16_t buf_adc[SIZE_BUF_ADC], t;
      uint8_t i, j;
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
        buf_adc[i] = analogRead(sensor);
    
        //TODO: need to check and REMOVE delay
        delay(50);
        //TODO: need to check and REMOVE delay
      }
    
      //take mediana from buffer
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
    
        for (j = 0; j < SIZE_BUF_ADC - i - 1; j++) {
          if (buf_adc[j] > buf_adc[j + 1]) {
            t = buf_adc[j];
            buf_adc[j] = buf_adc[j + 1];
            buf_adc[j + 1] = t;
          }
        }
      }
    
      return buf_adc[(SIZE_BUF_ADC - 1) / 2];
    
    }
    
    
    //    check box buttons
    void checkButtons(unsigned long current_time) {
    
      if (digitalRead(b1) and ((current_time - old_time) > 200) and !b1Status) {
    
        old_time = current_time;
        b1Status = true;
    
        if (LOW_PRESSURE >= PMIN) {
          //LOW_PRESSURE = 1.00;
          LOW_PRESSURE = PMIN;     // Тут тоже изменил
        }
        else {
          LOW_PRESSURE += 0.1;
        }
        drawMenu();
    
    
      }
      else if (!digitalRead(b1) and b1Status) {
        b1Status = false;
        saveDATA(0, LOW_PRESSURE * 10);
      }
    
      // check the second button
    
      if (digitalRead(b2) and ((current_time - old_time2) > 200) and !b2Status) {
    
        old_time2 = current_time;
        b2Status = true;
    
        if (HIGH_PRESSURE >= PMAX) {
         // HIGH_PRESSURE = 2.00;   // Тут есть изминение
          HIGH_PRESSURE = PMAX;
        }
        else {
          HIGH_PRESSURE += 0.1;
        }
        drawMenu();
    
      }
      else if (!digitalRead(b2) and b2Status) {
        b2Status = false;
        saveDATA(1, (HIGH_PRESSURE + 0.1) * 10);
      }
    
    }
    
    float readDATA(uint8_t addr) {
      return (float)EEPROM.read(addr) / 10.0;
    }
    
    void saveDATA(uint8_t addr, uint8_t data) {
    
      EEPROM.write(addr, data);
    
    }
0
0 / 0 / 0
Регистрация: 10.02.2017
Сообщений: 11
01.03.2018, 16:01  [ТС] 3
Код опробовал , что цифры менять - это понятно . Пробовал и другие значения тосовать. На данный момент в скетч подставил - #define PA 1.2 , #define PB 1.8 - при этих значениях вкл и выкл реле 1 и 2 . шкала так и осталась от 1.0 до 2.0 . Только понять не могу почему дисплей начинает мигать ( верхние цифры и шкала ) - когда давление ниже 1.0 ( то что надо ) и при выше 1.8 ( а надо при выше 2.0 ) Может подскажете . А может вообще можно от мигания избавится - подскажите кто знает . Ниже скетч , при свободном времени буду избавляться от задержки реле 1 и 2 - delay на millis , так как задержка будет не 0.5 секунд , а 20 . delay - будет тормозить всю программу .

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
        #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <EEPROM.h>
    
    //define zone---------------
    #define b1 6        //left LOW
    #define b2 5        //right HIGH
    #define ledG 9      //green led
    #define ledR 8      //red led
    #define ledY 7      //yellow led
    #define relay_1 2  //relay
        #define relay_2 3 
    #define sensor A0
    #define dV 0.004    //5/1023 - each 5V via analog signal
    #define PRESSURE_CORRECTION 0.4 //sensor correction
    #define PMIN 1.0   //min for LOW level
        #define PMAX 2.0    //max for HIGH level
          #define PA 1.2
          #define PB 1.8
    #define MAX_LCD_WIDTH 16
    
    //-----------------------------
    
    //init libs zone--------------
    LiquidCrystal_I2C lcd(0x3f, 16, 2); // Устанавливаем дисплей
    //-----------------------------
    
    bool b1Status = false;
    bool b2Status = false;
    bool working = false;
    bool SYSTEM_ERROR = false;
    uint8_t addr = 0;
    unsigned long current_time = 0;
    unsigned long old_time = 0;
    unsigned long old_time2 = 0;
    unsigned long test_millis = 0;
    unsigned long prev_predict = 0; //start working
    
    //-----------------------------------
    float LOW_PRESSURE = 1.0;
    float HIGH_PRESSURE = 2.0;
    //-----------------------------------
    float CURRENT_PRESSURE = 0.0; //current pressure
    float Vout = 0.0; //current pressure
    uint16_t analogV = 0;
    //--------------------------------
    
    void setup() {
      //
      //  Serial.begin(115200);
    
      //  try to load variables from EEPPROM arduino
      LOW_PRESSURE = readDATA(0);
      if (LOW_PRESSURE == 0.0) LOW_PRESSURE = 1.0;
    
      HIGH_PRESSURE = readDATA(1);
      if (HIGH_PRESSURE == 0.0) HIGH_PRESSURE = 2.0;
    
      current_time = millis();
    
      pinMode(b1, INPUT);
      pinMode(b2, INPUT);
      pinMode(ledG, OUTPUT);
      pinMode(ledR, OUTPUT);
      pinMode(ledY, OUTPUT);
      pinMode(relay_1, OUTPUT);
          pinMode(relay_2, OUTPUT);
      pinMode(sensor, INPUT);
    
      analogV = getAnalogData();
      //Vout = (analogV * dV1) - dP;
      CURRENT_PRESSURE = getPressure(analogV);
    
      lcd.init();
      lcd.backlight();// Включаем подсветку дисплея
      lcd.clear();
      drawMenu();
      digitalWrite(ledG, LOW);
      digitalWrite(ledY, LOW);
      digitalWrite(ledR, LOW);
    
      test_millis = current_time;
           
    }
         
    void loop() {
    
      current_time = millis();
    
      //regular get sensor data
      analogV = getAnalogData();
      checkSensorHealth(analogV);
    
      //false means that we do not switch ON relay according to predict....
      //checking and geting other functions
       {
        checkPressure();
        getPressure(analogV);
      }
      drawMenu();
      checkButtons(current_time);
    }
    
    //    update menu items
    void drawMenu() {
 
  delay(100);
 
  lcd.setCursor(0, 0); //x,y
  lcd.print(LOW_PRESSURE);
  lcd.setCursor(6, 0); //x,y
  lcd.print(CURRENT_PRESSURE);
  lcd.setCursor(12, 0); //x,y
  lcd.print(HIGH_PRESSURE);
 
  if (!SYSTEM_ERROR) {
 
    uint8_t blocks = (CURRENT_PRESSURE - LOW_PRESSURE) / ((HIGH_PRESSURE - LOW_PRESSURE) / MAX_LCD_WIDTH);
 
    for (uint8_t i = 15; i > blocks; i--) {
      lcd.setCursor(i, 1); //x,y
      lcd.write(254); //total hours working
    }
 
    //  draw blocks on LCD
    for (uint8_t i = 0; i < blocks - 1; i++) {
      lcd.setCursor(i, 1); //x,y
      lcd.write(255);
    }
  }
 
  else {
    lcd.setCursor(0, 1); //x,y
    lcd.print("low sensor data!");
  }
 
}
 
      
    
    //    calc pressure from converted analog signal
    float getPressure(uint16_t analog) {
    
      Vout = (analog * dV);
      //updated formula according to:
      // 0.4 - 0bar
      // 4.5 = 12bar (1.2Mpa)
      //−12x+4.1y+4.8=0 
      //we got the following: y(pressure) = (-48/41)+((120*x)/41) | x = voltage (analog * (5/1023) = 0.004))
      CURRENT_PRESSURE = (-48/41)+((120*Vout)/41)  + PRESSURE_CORRECTION; 
    
      return CURRENT_PRESSURE;
    }
    
    //    stop relay in case if sensor through the data less that normal and default 100 from A0 pin....
    void checkSensorHealth(uint16_t analog) {
      if ((analog <= 5) or (analog >= 8000) and !(SYSTEM_ERROR)) { //800~ its like ~7.5bar
        digitalWrite(ledR, HIGH);
        digitalWrite(relay_1, LOW); //switch OFF relay incase of error
            digitalWrite(relay_2, LOW);
        SYSTEM_ERROR = false;
      }
      if (SYSTEM_ERROR) {
        alarmErorr();
      }
    }
    
    //    alarm error
    void alarmErorr(void) {
      if (SYSTEM_ERROR) {
        digitalWrite(ledR, !digitalRead(ledR));
        if (working) {
          working = false;
          digitalWrite(ledG, LOW);
          digitalWrite(relay_1, LOW);
              digitalWrite(relay_2, LOW);
          digitalWrite(ledY, LOW); //switch ON predict LED
        }
    
      }
    }
    
    
    //    check and control main relay using predict param in case of prediction.....
    void checkPressure() {
    
     if (CURRENT_PRESSURE <= PA) {
        digitalWrite(ledG, HIGH);
        digitalWrite(relay_1, HIGH);
            delay (500);
            
            digitalWrite(relay_1, LOW);
            delay (500);
            digitalWrite(relay_2, LOW);
         working = true;
      }
    else if (CURRENT_PRESSURE >= PB) {
        lcd.clear();
        digitalWrite(ledG, LOW);
        digitalWrite(relay_2, HIGH);
            digitalWrite(relay_1, LOW);
            delay(500);
            digitalWrite(relay_2, LOW);
             delay (500);
        working = false;
        digitalWrite(ledY, LOW); //switch ON predict LED
      }
    }
    
    //    getting data from the analog arduino pin - default A0 using TEST param for local testing without sensor.....
    uint16_t getAnalogData(void) {
    
      const uint8_t SIZE_BUF_ADC = 5;
      uint16_t buf_adc[SIZE_BUF_ADC], t;
      uint8_t i, j;
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
        buf_adc[i] = analogRead(sensor);
    
        //TODO: need to check and REMOVE delay
        delay(50);
        //TODO: need to check and REMOVE delay
      }
    
      //take mediana from buffer
    
      for (i = 0; i < SIZE_BUF_ADC; i++) {
    
        for (j = 0; j < SIZE_BUF_ADC - i - 1; j++) {
          if (buf_adc[j] > buf_adc[j + 1]) {
            t = buf_adc[j];
            buf_adc[j] = buf_adc[j + 1];
            buf_adc[j + 1] = t;
          }
        }
      }
    
      return buf_adc[(SIZE_BUF_ADC - 1) / 2];
    
    }
    
    
    //    check box buttons
    void checkButtons(unsigned long current_time) {
    
      if (digitalRead(b1) and ((current_time - old_time) > 200) and !b1Status) {
    
        old_time = current_time;
        b1Status = true;
    
        if (LOW_PRESSURE >= PMIN) {
          LOW_PRESSURE = 1.0;
        }
        else {
          LOW_PRESSURE += 0.1;
        }
        drawMenu();
    
    
      }
      else if (!digitalRead(b1) and b1Status) {
        b1Status = false;
        saveDATA(0, LOW_PRESSURE * 10);
      }
    
      // check the second button
    
      if (digitalRead(b2) and ((current_time - old_time2) > 200) and !b2Status) {
    
        old_time2 = current_time;
        b2Status = true;
    
        if (HIGH_PRESSURE >= PMAX) {
          HIGH_PRESSURE = 2.0;
        }
        else {
          HIGH_PRESSURE += 0.1;
        }
        drawMenu();
    
      }
      else if (!digitalRead(b2) and b2Status) {
        b2Status = false;
        saveDATA(1, (HIGH_PRESSURE + 0.1) * 10);
      }
    
    }
    
    float readDATA(uint8_t addr) {
      return (float)EEPROM.read(addr) / 10.0;
    }
    
    void saveDATA(uint8_t addr, uint8_t data) {
    
      EEPROM.write(addr, data);
    
    }
0
Модератор
Эксперт по электронике
8490 / 6317 / 854
Регистрация: 14.02.2011
Сообщений: 21,886
01.03.2018, 16:59 4
Barsik7, пользуйтесь тэгами выделения кода
0
348 / 282 / 144
Регистрация: 08.04.2013
Сообщений: 1,230
01.03.2018, 18:35 5
вы точно все места поменяли, чтобы изменить 1.0 и 2.0 там надо менять в 6 местах
в начале 4 и в конце 2
0
348 / 282 / 144
Регистрация: 08.04.2013
Сообщений: 1,230
03.03.2018, 08:40 6
Хотелось бы уточнить, вы хотите чтобы реле работала в режиме 2с Вкл -20 с выкл при условии, если давление упадет ниже 0,7 до достижения 2,3 ? В чем прикол такого действия?
0
0 / 0 / 0
Регистрация: 10.02.2017
Сообщений: 11
03.03.2018, 11:05  [ТС] 7
Допустим бак с водой , с этого бака идет разбор воды , то больше то меньше , на заполнение бака с водой - стоит электро задвижка ( реле 1 - открывает , реле 2 - закрывает электро задвижку ) а электро задвижка при среднем давлении открыта допустим на 50% . Давление падает реле 1 вкл. на 2 секунды и выкл. на 20 секунд , если будет включено на большее время задвижка откроется слишком много .
0
348 / 282 / 144
Регистрация: 08.04.2013
Сообщений: 1,230
03.03.2018, 17:07 8
вопрос 1. Вы пишете электро задвижка при среднем давлении открыта допустим на 50%. Где расположен ваш датчик давления? и для чего?
вопрос 2 вам. вы открыли задвижку ( реле отработала 2 с. выключилась на 20 секунд) и что должно произойти потом, и какое отношение дальше будет к текущей воде далнейшие показания давления.
какое напряжение будете использовать, и что открывает задвижку
Вы лучше без "предположении" опишите ваш технологический процесс, если поймем чего вы добиваетесь, может подскажем.
Если просто хотите заполнить бак водой, так для этого надо уровень воды в баке определять, а не давление воды в системе подачи мерить
0
0 / 0 / 0
Регистрация: 10.02.2017
Сообщений: 11
03.03.2018, 22:40  [ТС] 9
датчик давления в баке. На датчиках уровня - сделать автоматику легко , но при больших объемах воды и учитывая что вода горячая ( бак аккумулятор горячей воды ) - датчики нужно будет часто чистить . На счет давление и уровня воды , вы правы лучше измерять в метрах . В 1.0 - давлении =10 метров водяного столба . Сигнал с датчика давления усиливается операционным усилителем и в обратную связь ставится подстроечный резистор меняя кофициэнт усиления - подгоняя под уровень воды на дисплее . и хотя в скетче 1.0 и 2.0 давление - буду пробовать подогнать под давление в баке 0.1 и 0.2 - что соответствует 1 метру и 2 метрам.
Алгоритм программы простой . при 1.2 до 1.8 ( пока примерно - будут при наладке изменены ) метра уровень воды , на электро задвижку напряжение не подается , при уменьшении уровня ниже 1.2 - реле 1 вкл. на 2 секунды и выкл. на 20 секунд ( эти 2 и 20 секунд - пока примерно , при наладке будут подгоняться ) реле 1 будет работать в таком цикле пока уровень не поднимется до 1.2 метра .Аналогично по верхнему уровню аналогично . А электро задвижка нужна для - кательная греет воду , вода через теплообменник подается в бак аккумулятор горячей воды . Если электро задвижку будет открыть на 100 % вода не будет успевать нагреваться.

Добавлено через 1 час 19 минут
В принципе можно реализовать на 2 микроконтролерах . в первом основная программа , а второй мк будет задовать задержки с delay для двух реле . Реализовывать данный проект по установке буду летом . Но для спортивного интереса хотелось бы написать программу для 1 мк.
0
348 / 282 / 144
Регистрация: 08.04.2013
Сообщений: 1,230
04.03.2018, 08:42 10
Я так понял задвижка открывается на 2 сек. и закрывается на 20 сек.
Цитата Сообщение от Barsik7 Посмотреть сообщение
при уменьшении уровня ниже 1.2 - реле 1 вкл. на 2 секунды и выкл. на 20 секунд ( эти 2 и 20 секунд - пока примерно , при наладке будут подгоняться ) реле 1 будет работать в таком цикле пока уровень не поднимется до 1.2 метра
опять вопрос???
Тут наверное ошибочка, по данному алгоритму надо уровень довести до 1,8

Добавлено через 8 минут
Здесь наверное надо 1 реле, соленоид и регулировочный кран, который вы руками отрегулируете на нужный объем воды, чтоб успевал нагреться. Вопрос опять возник, какой объем воды надо прогнать за единицу времени? 1сек. 1 мин.

Добавлено через 17 минут
Итог как минимум: Надо в (Емкости пока неопределенного объема) держать воду в определенных пределах , при деопазоне определенных температур?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.03.2018, 08:42

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

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

Вывод информации с датчика arduino в приложение на python
Можно пожалуйста спросить? Начал соединять ардуино с питоном и столкнулся с проблемой. Когда я...

Управление шаговым двигателем с драйвером а4988
Собрал схему на breadborde для управления шаговым двигателем на основе драйвера a4988, где то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.