Jump to content
ironmass

Электроника Для Компрессора

Recommended Posts

Всем доброго времени суток!Я новичек,так что сильно не ругайтесь.Собрал компрессор на базе ЗИЛ-130,вот теперь мудрю электронику,век технологий как не как.Алгоритм работы программы такой.При вкл.питания МК опрашивает датчики температуры DS18b20 выводит на семисегментник температуру первого датчика,после этого опрашивает второй датчик и если температура больше 40 гр. то опрашивает датчик давления и если он разрешает запуск то включает нужные порты и ставит флаг что компрессор работает.Дальше продолжает выводить температуру первого датчика на индикатор и опрашивать состояние датчика давления.когда датчик давления сработал,то выключаются нужные порты и ставиться флаг выключения.А если температура второго датчика меньше 40 гр. то вкл. подогреватель.Нашел схему термометра с несколькими датчиками и немного дописал под свои нужды.Температуру показывает,а остальное не делает.Уже всю голову сломал,не пойму что не так.Подскажите если не сложно.

#include <tiny2313.h>
// 1 Wire Bus functions
#asm
.equ __w1_port=0x12 ;PORTD
.equ __w1_bit=6
#endasm
// DS18x20 Temperature Sensor functions
#include "ds18x20_v2.h"
#include <delay.h>
#include <bcd.h>
//---------------------------------------
#define A 2
#define B 32
#define C 4
#define D 64
#define E 128
#define F 1
#define G 1
static flash unsigned char digits_PA[] = {
(A+F), // 0
(0), // 1
(A), // 2
(A), // 3
(F), // 4
(A+F), // 5
(A+F), // 6
(A), // 7
(A+F), // 8
(A+F), // 9
(A+F), // A - 10
(F), // b - 11
(A+F), // C - 12
(0), // d - 13
(A+F), // E - 14
(A+F), // F - 15
(0), // 16 - знак минус
(A+F), // 17 - символ градус цельсия
(0) // 18 - пусто
};
static flash unsigned char digits_PB[] = {
(B+C+D+E), // 0
(B+C),	 // 1
(B+D+E+G), // 2
(B+C+D+G), // 3
(B+C+G),	 // 4
(C+D+G),	 // 5
(C+D+E+G), // 6
(B+C),	 // 7
(B+C+D+E+G), // 8
(B+C+D+G), // 9
(B+C+E+G), // A - 10
(C+D+E+G), // b - 11
(D+E),	 // C - 12
(B+C+D+E+G), // d - 13
(D+E+G),	 // E - 14
(E+G),	 // F - 15
(G),		 // 16 - знак минус
(B+G),	 // 17 - символ градус цельсия
(0)		 // 18 - пусто
};

#define MINUS 16
#define GRADUS 17
#define PROBEL 18
#define SYMBOL_F 15

// K1 - PORTD.0-1, K2 - PORTD.2-3, K3 - PORTD.4-5
static flash unsigned char cursor[]={0b1110100, 0b1111000, 0b1101100};
unsigned char digit_out[3], cur_dig;
bit zpt_ON;
int temperature;	 // то, что возвращает верхний датчик
int temperature1;	 // то, что возвращает нижний датчик
bit job=1;			 //переменная состояния работы 1-выкл,0-вкл

// maximum number of DS1820/DS18S20/DS18B20 devices connected to the 1 Wire bus
#define MAX_DS18x20 4
// DS1820/DS18S20/DS18B20 devices ROM code storage area, 9 bytes are used for each device
unsigned char rom_code[MAX_DS18x20][9];

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {

PORTD|=0b00111100; // потушить все (биты всех знакомест "1" - для Общ.кат.)

PORTA=digits_PA[digit_out[cur_dig]]; // символ на экран
PORTB=digits_PB[digit_out[cur_dig]];
if ((zpt_ON == 1) && (cur_dig == 1)) PORTB.4=1; // запятая во втором разряде (нумерация нач. с нуля)	
PORTD&=(cursor[cur_dig]); // засветить нужный бит (бит знакоместа в "0" - для Общ.кат.)
cur_dig++; if (cur_dig > 2) cur_dig=0;
}
// ----------------------------------------------------------------------------
void view_term(void) {
unsigned char celie, drob, tmp;
unsigned int temp, celie_tmp, drob_tmp;

temp = (unsigned int) temperature;

if (temperature>=0) {
digit_out[0]=PROBEL;	 // первый символ (сотни) пустой
} else {	
temp = ( ~temp ) + 0x0001; // если число отрицательное перевести его в норм.вид
digit_out[0]=MINUS;	 // и высветить знак минус (в дальнейшем атрибут отр.темп.)
};
//digit_out[3]=GRADUS;
zpt_ON=1;
celie_tmp = temp >> 4;			 // целая часть числа
drob_tmp = temp & 0x000F;		 // дробная часть числа с точностью 1/16 градуса
drob = (unsigned char) ((drob_tmp * 10) / 16); // преобразование дробной части в формате "1/16 градуса" в десятичный формат с точностью 0,1 градуса
celie = (unsigned char) celie_tmp; // я люблю явное преведение типов
if (celie >= 100) {tmp=bin2bcd(celie-100); digit_out[0] = 1; } else { tmp=bin2bcd(celie); } // вычислить целую часть
if ((celie >= 100) || ((digit_out[0] == MINUS) && (celie >= 10))) { // если больше 100,0 гр. или если темп. меньше -10 точность 1 гр.
zpt_ON=0;
digit_out[1] = tmp >> 4; // десятки
digit_out[2] = tmp & 0x0F; // единицы
}
if ((digit_out[0] == MINUS) && (celie < 10)) { // если темп.меньше 0 и больше -10 точность 0,1 гр.
digit_out[1] = celie; // единицы
digit_out[2] = drob; // дробная часть
}
if ((digit_out[0] == PROBEL) && (celie < 100)) { // если темп. меньше 100,0 гр и больше 0 гр точность 0,1 гр.
if (tmp >> 4) digit_out[0] = tmp >> 4; // десятки - если десятков нет то и не показывать
digit_out[1] = tmp & 0x0F;			 // единицы
digit_out[2] = drob;				 // дробная часть
}
} // -------------------------------------------------------------------------

//================================== main =====================================
void main(void) {
unsigned char i, ds18x20_devices;

PORTA=0x00;
DDRA=0x03;

PORTB=0x00;
DDRB=0xFF;
// Port D initialization
PORTD=0b0100000;// State6=1 State5=T State4=1 State3=1 State2=1 State1=1 State0=1
DDRD=0b1011111; // Func6=In Func5=In Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;
// 1 Wire Bus initialization
w1_init();
// Determine the number of DS18x20 devices connected to the 1 Wire bus
ds18x20_devices=w1_search(0xf0,rom_code);
// Global enable interrupts
#asm("sei")
// высветить на индикаторе F 'кол-во найденых устройств'
digit_out[0]=SYMBOL_F;
digit_out[1]=PROBEL;
digit_out[2]=ds18x20_devices;
// т.к. при первом чтении датчиков считывается мусор
// первое чтение датчиков делаем в холостую
if (ds18x20_devices >= 1) {
for (i=0;i<ds18x20_devices;i++) {
if (rom_code[i][0] == DS18B20_FAMILY_CODE){
temperature=ds18b20_temperature(&rom_code[i][0]);
}
//if (rom_code[i][0] == DS18S20_FAMILY_CODE){
// temperature=ds18s20_temperature(&rom_code[i][0]);
}
delay_ms(1000);

} else {
delay_ms(2000);
}

// -------------------------------- рабочая часть -----------------------------------
while (1) {
		 temperature=ds18b20_temperature(&rom_code[1][0]); //опрос верхнего датчика
		 view_term();

		 temperature=ds18b20_temperature(&rom_code[0][0]); //опрос нижнего датчика
		 temperature1=temperature;

	 if (temperature1>=40)
{		 if (PIND.5==1)	 //опрос датчика давления 1-выкл,0-вкл
{		 if (job==1)	 //состояние работы 1-выкл,0-вкл
{
		 PORTB.3=0; //Выключение подогревателя
		 PORTD.1=1; //Включение клапана пуска
		 delay_ms(500);
		 PORTB.1=1; //Запуск двигателя
		 delay_ms(1000);
		 PORTD.1=0; //Выключение клапана пуска

		 job=0;	 //состояние работы вкл
}
}			
		 if (PIND.5==0) //опрос датчика давления 1-выкл,0-вкл
{			 if (job==0) //состояние работы 1-выкл,0-вкл
{				 PORTB.1=0; //Остановка двигателя
			 job=1;	 //состояние работы выкл
}
}
}

else {
PORTB.3=1; //Включение подогревателя
}

};// ----------------------------- рабочая часть (end) -----------------------------------


} // =================================== end main =========================================


//
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The End -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//

Share this post


Link to post
Share on other sites

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

В компрессоре ЗИЛ-130, главное удерживать в картере достаточный уровень смазки.

И обеспечить шкивами, достаточный пусковой момент и скорость вращения (производительность).

Больше 8 Атм он не выдаст - оптимально 3-5 Атм и ресивер около 50 литров.

Температура компрессора (без охлаждения) при этом редко подымается выше +60 С.

Его длительная рабочая температура (с водяным охлаждением), достигает + 115 С.

Share this post


Link to post
Share on other sites

Изготовление 2-х слойных плат от 2$, а 4-х слойных от 5$!

Быстрое изготовление прототипа платы всего за 24 часа! Прямая доставка с нашей фабрики!

Смотрите видео о фабрике JLCPCB: https://youtu.be/_XCznQFV-Mw

Посетите первую электронную выставку JLCPCB https://jlcpcb.com/E-exhibition чтобы получить купоны и выиграть iPhone 12, 3D-принтер и так далее...

Больше 8 Атм он не выдаст - оптимально 3-5 Атм и ресивер около 50 литров.

И с чего вы взяли что он больше 8 атм.не выдаст.Я лично на своем компрессоре накачивал 150 литровый ресивер до 11 атм.потом просто лопнул шланг.Я новичек в програмировании,но далеко не новичек в самодельных устройствах,Да и этот форум не про то как лучше использовать компрессор.Я пришел сюда за помощью в написании программы для моего устройства.Если вам интересно как работает мой компрессор,то пишите в личку,расскажу что да как.Я хочу познать программирование и сделать полезное для моего устройста,совместить два дела одновременно.

Share this post


Link to post
Share on other sites

Вебинар «Практическое использование TrustZone в STM32L5»(10.12.2020)

Приглашаем на вебинар, посвященный экосистеме безопасности и возможностях, которые появились у разработчиков благодаря новой технологии TrustZone в микроконтроллерах STM32L5. Программа рассчитана на технических специалистов и тех, кто уже знаком с основами защиты ПО в STM32.

Подробнее

Здравствуйте ironmass. А какой у вас датчик давления? Да, и алгоритм работы компрессора опишите по порядку.

Share this post


Link to post
Share on other sites

Снижена цена на AC/DC и DC/DC преобразователи Mornsun в Компэл!

Компэл и компания Mornsun снизили цены на преобразователи AC/DC-преобразователи семейств LS и LDE. По привлекательной цене также предлагаются DC/DC-преобразователи изолированных семейств поколений R2 и R3 различного конструктивного исполнения.

Подробнее

Больше 8 Атм он не выдаст - оптимально 3-5 Атм и ресивер около 50 литров.

Ну не знаю про какой компрессор вы говорите, но 2-ух поршневой кладёт стрелку 15кг/с2 (сбросник заело).

Share this post


Link to post
Share on other sites

Материалы вебинара: «Силовые компоненты Wolfspeed на основе карбида кремния (SiC)»

Вы можете посмотреть видеозапись вебинара «Силовые компоненты Wolfspeed на основе карбида кремния (SiC)», ознакомиться с ответами на вопросы и презентацией, в которой вы найдете много полезных ссылок, в том числе подробнее раскрывающих ответы на вопросы.

Подробнее

Что конкретно он не делает. У вас в главной программе два условия хоть в какое то из них программа попадает? что на портах по управлению делается?

Share this post


Link to post
Share on other sites

Всем привет!Не стал создавать новую тему.Версия кода что описывалась выше была переписанна и успешно отработало почти год.Теперь решил обновить,сделать версию 2.0.И опять проблема.

Написал программу управляющая компрессором,которая следит за работой,измеряет температуру,выводит её на 4-х led индикатор.Все хорошо,но часто происходит что на индикаторе перепрыгивают символы(цифры).Например показывает температуру двух датчиков 21 и 54,потом почему-то прыгнет на 41 и 54,или 21 и 14.,а если программно отключить два символа(т.е. вывод только одной температуры)то нечего не прыгает.Все голову уже сломал,из-за чего,перепробывал многое менять,Прошу помогите.И да,сильно не материтесь на код программы,я только недавно начал писать на СИ.

/*****************************************************
Version :2.00 
Date    : 12.02.2017
Chip type               : mega8
AVR Core Clock frequency: 8,000000 MHz
Memory model            : mega
External RAM size       : 0
Data Stack size         : 32
*****************************************************/
 
#include <mega8.h>
#include <delay.h> 
#asm
   .equ __w1_port=0x15 ;PORTC  
   .equ __w1_bit=5
#endasm
#include <1wire.h>
#include <ds18b20.h>
 
unsigned char ds18b20_devices;//переменная в которой хранится количество присоеденённых датчиков
unsigned char ds18b20_rom_codes[3][9], i=1;
volatile unsigned char temper,temper1,temper3,number,number1,number2,number3,number4;//переменные для хранения температур        
bit job=1,err=0; //переменные состояния работы

//Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void){     
        
        PORTB.0=0; PORTD.5=0; PORTD.7=0; PORTD.6=0;// потушить все биты всех знакомест
        
        
        if(i==1){number=number1;PORTB.0=1;}    //засветить первый бит
        if(i==2){number=number2;PORTD.5=1;}    //засветить второй бит
        if(i==3){number=number3;PORTD.7=1;}   //засветить третий бит
        if(i==4){number=number4;PORTD.6=1;i=0;}//засветить четвертый бит
       
        
      switch(number){//символ на иникатор  
         case 0:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=1; break;}//0 
         case 1:{PORTD.2=1;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=1;PORTD.0=1; break;}//1 
         case 2:{PORTD.2=0;PORTD.3=0;PORTB.7=1;PORTB.6=0;PORTD.4=0;PORTD.1=1;PORTD.0=0; break;}//2 
         case 3:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=1;PORTD.0=0; break;}//3 
         case 4:{PORTD.2=1;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=0;PORTD.0=0; break;}//4 
         case 5:{PORTD.2=0;PORTD.3=1;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=0;PORTD.0=0; break;}//5 
         case 6:{PORTD.2=0;PORTD.3=1;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=0; break;}//6 
         case 7:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=1;PORTD.4=1;PORTD.1=1;PORTD.0=1; break;}//7 
         case 8:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.1=0;PORTD.0=0; break;}//8 
         case 9:{PORTD.2=0;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=1;PORTD.1=0;PORTD.0=0; break;}//9   
         case 10:{PORTD.2=1;PORTD.1=1;PORTD.3=0;PORTB.7=0;PORTB.6=0;PORTD.4=0;PORTD.0=0; break;}}//d
         i++;}  

void view_term_mot(void) 
{ 
              number3=temper3/10;      //вычислить десятки      
              number4=temper3%10;    //вычислить единицы
}       

void view_term_hot(void) 
{ 
              number1=temper1/10;      //вычислить десятки              
              number2=temper1%10;    //вычислить единицы 
              
}              
void view_term(void) 
{ 
              number1=temper/10;      //вычислить десятки              
              number2=temper%10;    //вычислить единицы 
              
}
void main(void)
{
PORTC=0x00;DDRC=0x3F;PORTB=0x02;DDRB=0xFD;PORTD=0x00;DDRD=0xFF;
 
// Clock value: 1000,000 kHz
 //Mode: CTC top=OCR1A
TCCR1A=0x00;
TCCR1B=0x0A;//настройка таймера 1
OCR1AH=0x06;
OCR1AL=0x76;

TIMSK=0x10;//запуск таймера 1 в режиме СТС top=OCR1A  
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);//ищим датчики и считываем rom-коды датчиков

#asm("sei")//разрешить глобальные прерывание

// высветить на индикаторе кол-во найденых датчиков
number1=10;              //символ d
number2=ds18b20_devices;//кол-во датчиков
number3=10;             //символ d
number4=ds18b20_devices;//кол-во датчиков

// т.к. при первом чтении датчиков считывается мусор 
// первое чтение датчиков делаем в холостую
if (ds18b20_devices >= 1) {
         temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);//опрос верхнего датчика
         delay_ms(500);//ждем 500 мс для получения температуры верхнего датчика
         temper1=ds18b20_temperature(&ds18b20_rom_codes[1][0]);//опрос нижнего датчика
         delay_ms(500);//ждем 500 мс для получения температуры нижнего датчика
         temper3=ds18b20_temperature(&ds18b20_rom_codes[2][0]);//опрос датчика двтгателя
         delay_ms(500);}//ждем 500 мс для получения температуры датчика двигателя
while (ds18b20_devices>0){    //если датчиков больше 1 то бесконечный цикл
         
        temper3=ds18b20_temperature(&ds18b20_rom_codes[2][0]);//опрос датчика двигателя
         view_term_mot();
        
        if(err==0){         //если разрешенно включение подогревателя то
         if (temper1<=20){     //если температура нижнего датчика меньше 20
          temper1=ds18b20_temperature(&ds18b20_rom_codes[1][0]);//опрос нижнего датчика 
           delay_ms(200); //ждем 500 мс для получения температуры нижнего датчика
            view_term_hot();//выводим температуру
             PORTC.4=1;    //Включение подогревателя
              PORTC.2=0;    //Остановка двигателя на всякий случай
               PORTC.3=0;}}      //Отключение помпы на всякий случай
          
               
        if (temper1>=20){   //если температура нижнего датчика больше или равно 20     
         temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);//опрос верхнего датчика
          delay_ms(200);//ждем 500 мс для получения температуры верхнего датчика
           view_term(); //выводим температуру верхнего датчика на индикатор
               if (PINB.1==0){       //если датчик давления выключен
                if (job==1){        //если состояние работы "вкл"
                 PORTC.4=0;        //Выключение подогревателя
                  PORTC.3=1;      //Включение помпы
                   PORTC.0=1;     //Включение клапана сброса давления
                    delay_ms(3000); //подождем 3 сек для сброса давления в магистрале
                     PORTC.2=1;    //Запуск двигателя
                      delay_ms(3000); //подождем 3 сек для полного запуска двигателя
                       PORTC.0=0;    //Отключение клапана сброса давления
                        PORTC.1=1;  //Сигнал на включение второму компрессору
                         err=1;      //запрет на включение подогревателя
                          job=0;}}}      //установить состояние работы "выкл"
 
               
        if (PINB.1==1){ //если датчик давления включен
         if (job==0){  //если состояние работы "выкл"
          PORTC.2=0;    //Остановка двигателя
           PORTC.1=0;  //Сигнал на отключение второму компрессору
            PORTC.0=1;     //Включение клапана сброса давления
             delay_ms(3000); //подождем 3 сек для сброса давления в магистрале
              PORTC.0=0;    //Отключение клапана сброса давления
               job=1;}  //установить состояние работы "вкл"
          if (temper<=30){   //если температура верхнего датчика меньше или равно 30
           PORTC.3=0;}}      //Отключение помпы
          
        
        if (temper3>=60){   //если температура двигателя больше или равно 60
         PORTC.2=0;}    //Остановка двигателя   
          if (temper3<=45){   //если температура двигателя упала до 45
           job=1;}}}  //установить состояние работы "вкл"

 

Edited by ironmass

Share this post


Link to post
Share on other sites

Попробуйте на время вычислений запретить прерывания.

А также засунуть текст программы под спойлер.


Я не раздаю удочки. Я продаю рыбу.

Share this post


Link to post
Share on other sites

пробывал запрещать прерывание на момент вычислений,все равно прыгают.Скорей всего опрос датчиков идет как-то не так,а как исправить не знаю

Share this post


Link to post
Share on other sites

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

Для серьезных поделок нужен совершенно другой подход в программировании.

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

Конечные автоматы. Гугл. Цикл статей Татарчевского.

Псевдопараллельность процессов. Дробление выполнения модулей. Условиями, флагами, состояниями конечных автоматов. Максимально в программах избавляться от долгих циклов. Каждый модуль за итерацию основного цикла выполняет часть кода. Итерация основного цикла должна с запасом впаковываться в системный тик.

Edited by demiurg1978

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...