- Родительская категория: Проекты
- Категория: Электроника
- Автор: FurCat
- Просмотров: 30540
Электронный регулятор для компрессора
Знакомый, занимающийся аэрографией, попросил сделать ему электронный регулятор для компрессора, который бы поддерживал нужное давление.
Имелся компрессор — обычный автомобильный компрессор для накачки колёс с питанием от 12в, всё остальное прнишлось придумывать из того, что можно несложно достать.
Итак, общая конструкция, появившаяся в голове, выглядит так.
Компрессор нагнетает воздух в некое хранилище (ресивер), из ресивера воздух подаётся на
пульверизатор, для контроля давления в ресивере нужен датчик давления воздуха, а также электронная схема, контролирующая работу электродвигателя компрессора и обладающая гистерезисом.
Изучив матчасть по теме датчиков давления, пришёл к выводу, что покупать специализированный электронный датчик слишком накладно (цены на датчики). Согласитесь, цены очень кусачие...
Нам нужно поддерживтаь давление в районе 1....2 кгс/см², и сразу приходит идея использования обычного автомобильного датчика. Я раздобыл вот такую таблицу, которой охотно с вами поделюсь:
Зайдя в ближайший автомагазин, я обнаружил ММ358 за 160руб.
{ads2}Дальше, в принципе, соединить воедино датчик, компрессор и ресиверы несложно: немного трубочек от стеклоомывателя, тройников аквариумных (для пузырения воздуха) из зоомагазина, немного клея, скотча..... и готово, имеем компрессор, который способен нагнетать воздух в ресивер, и датчик давления, контролирующий давление в ресивере.
Теперь электронная часть.
В принципе, можно было сделать весь регулятор на одном крохотном ОУ, например LM358, что я и сделал поначалу, но настройка и регулровка ОС такой схемы высосала из меня все соки, поэтому я взял МК atmega8, светодиодный семисегментник, стабилизатор напряжения, немного рассыпухи...
Схема в итоге у меня получилась вот такая:
Стабилизатор на 5в ( на схеме это LM7805, но на самом деле я применил импульсный на LM2596, покупал вот тут, но можно применить и ранее разработанный мною; линейный стабилизатор даже в корпусе ТО220 потребует теплоотвода при питающем напряжении 12....16в).
Стабилизированное напряжение величиной 5в питает МК и делитель напряжения, образованный резистором R1 240 Ом и датчиком давления RV1, имеющим согласно таблице сопротивление 195 Ом.
Теперь нам осталось оцифровать напряжение с датчика давления и вывести на индикатор, заодно управляя компрессором.
В общем, чтобы долго не мучиться с измерениями напряжений на датчике и всякими расчётами, я сделал проще: для начала вывел на индикатор значение АЦП при различных давлениях в диапазоне от 0 до 3 кгс/см², получилась примерно вот такая ситуация:
Давление | Показания ADC |
0 кгс/см² | 761 |
1 кгс/см² | 705 |
2 кгс/см² | 612 |
3 кгс/см² | 515 |
Отобразив всё это в Excel, я увидел примерно вот такую картину:
Т. к. датчик представляет из себя проволочный переменный резистор, небольшая нелинейность на графике из-за того, что показания давления снимались со встроенного в компрессор (естественно китайского производства) манометра.
Порт D МК управляет сегментами, три младших пина порта B управляют разрядами индикатора, ADC0/PC0 - вход напряжения на АЦП, PC2 - выход на управление компрессором.
Стабилитрон D2 на всякий случай, чтобы защитить вход АЦП от большого напряжения в случае обрыва цепи датчика. Светодиод D3 индицирует включение компрессора.
Далее непосредственно сама программа:
{code}
/* Программа цифрового манометра на
Mega8
Показывает давление в ресивере
и управляет компрессором
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>
#define SPACE 0b00000000 /* Символ пустого места */
#define COMM 0b00000100 /* Символ точки */
#define NEG_CHAR 0b00000001 /* Минус */
#define MAX_SIZE 3 /* Число знакомест дисплея */
#define ROWS PORTD /* порт «строк» дисплея, т.е. управления сегментами */
#define COLS PORTB /* порт управления «столбцами», т.е. общими катодами */
#define AVERAGE 64 /* Число замеров для усреднения */
#define DIG_BASE 10 /* Основание системы счисления */
/* сегменты BFAEDHCG =1= =2= =3= =4= =5= =6= =7= =8= =9= */
unsigned char SYMBOLS[10] = {0b11111010, 0b10000010, 0b10111001, 0b10101011, 0b11000011, 0b01101011, 0b01111011, 0b10100010, 0b11111011, 0b11101011};
volatile unsigned char SCR[MAX_SIZE];
void initialize(void){
DDRB = 0xFF; /* Порт В разряды */
DDRD = 0xFF; /* Порт D сегменты */
DDRC = 0x00;
DDRC |= (1 << 2);
TCCR0 = _BV(CS01); /* Делитель TIMER0 на /8 */
TIMSK = _BV(TOIE0); /* Включаем прерывание по переполнению TIMER0 */
ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS0); /* Включаем АЦП и ставим делитель /128 */
ADMUX = _BV(REFS1) | _BV(REFS0);
wdt_enable(WDTO_1S); // Включаем сторожевой таймер и настраиваем на 1 сек
}
static uint16_t get_adc(void){
static uint16_t values[AVERAGE];
static uint16_t current = 0;
uint32_t result = 0;
uint16_t i;
ADCSRA = ADCSRA | _BV(ADSC); /* Запускаем АЦП преобразование */
while((ADCSRA & _BV(ADIF)) == 0); /* Проверяем окончание АЦП */
values[current] = ADC;
for(i=0; i<AVERAGE; i++)
result = result + values[i];
if(++current>=AVERAGE)current=0;
return result / AVERAGE;
}
uint16_t mashtab(uint16_t value){
return value = value;
}
void put_to_scr(uint16_t value){
int i, m, sign = 0;
if(value <0){
sign = 1;
value *= -1;
}
i=MAX_SIZE-1;
do{
m = value % DIG_BASE;
if((value==0)&&(i!=(MAX_SIZE-1)))
break;
else
SCR[i] = SYMBOLS[m];
SCR[MAX_SIZE-3] |= COMM;
value /= DIG_BASE;
} while (--i >= 0);
if (i < 0) return;
if (sign) SCR[i--] = NEG_CHAR;
for(; i>=0;i--) SCR[i] =SYMBOLS[0] ;
}
int main(void){
uint16_t value;
uint8_t giss;
giss = 0;
initialize();
sei();
while(1){
wdt_reset();
value = get_adc();
if (value > 761) value = 761;
else value = value;
value = (761 - value) * 110 / 100;
if (value < 150) /* Значение включения компрессора */
PORTC |= (1 << 2);
if (value > 160)
PORTC &= ~(1 << 2); /* Значение выключения компрессора */
put_to_scr(value); /* Вывод значения на индикатор */
}
}
ISR(TIMER0_OVF_vect){ /* Динамическая индикация по таймеру 0 */
static unsigned char pos = 0;
COLS = 0xFF;
ROWS = SCR[pos];
COLS = ~(1 << pos);
if(++pos == MAX_SIZE) pos = 0;
}
{/code}
Запускаем АЦП, усредняем результат АЦП, используя последние 64 замера, масштабируем отсчёты АЦП в значения кг/см², выводим на индикатор в виде 0.00 и управляем компрессором.
Строка #define AVERAGE 64 - это количество замеров для усреднения
Строка value = (761 - value) * 110 / 100 масштабирует значение АЦП в значение кгс/см² (вернее, в кПа/см², т. е. значение 2кгс в программе соответствует значению 200кПа), а точку после первого разряда программа выводит постоянно, незначащие нули, естественно, мы не гасим.
Строка if (value < 150) - это давление для включения компрессора, 150 значит 1,5кгс/см²
Строка if (value > 160) - это давление для выключения компрессора, 160 значит 1,6кгс/см²
Строка if (value > 761) value = 761 необходима, т. к. возможна ситуация, когда напряжение на датчике выйдет за разумный диапазон, и тогда при давлении ниже 0 значение АЦП возрастёт выше 761, что испортит правильность масштабирования.
Программа писалась в AVR Studio 4, печатная плата рисовалась в Sprint-Layout 5.0.
PCB была разведена под стабилизатор LM78L05 в корпусе ТО92, что оказалось ошибкой из-за его недостаточной мощности. В моём случае питающее напряжение компрессора оказалось 16в, и даже стабилизатор в ТО220 сильно грелся, посему пришлось применить отдельную плату стабилизатора на LM2596
Файлы проекта для AVRStudio 4 и разводка для Sprint-Layout 5.0 прилагаю в архивах.
Пара фоток того, что получилось:
Видео на форуме.
Надеюсь кому-то пригодится эта статья.
{plusone}
Комментарии
а откуда там взяться большому напряжению?
там ведь 5 в идёт после стабилизатора,
На основе этой схемы разработал:
- манометр-вольтм етр автомобильный,
- вольтметр-ампер метр для блока питания,
- термометр для паяльника
и т.д., идей еще много.
RSS лента комментариев этой записи