Код написан на Си для Атмеги 328Р необходимо переписать на Ардуино
LCD1602 в коде был подключен через 12 пинов необходимо чтобы он был подключен по I2C
Что делает код
у него два датчика один температуры pt1000
Второй датчик давления работает в диапазоне U 0-10В
датчик температуры выводится на экран дисплея LCD 1602
по датчику давления зажигаем светодиоды 4 штуки также выводится давление на дисплей
есть у меня проект в протеусе могу выслать на почту
есть макетная плата все работает могу видео скинуть что он делает
По сумме 5000 рублей. Но пожалуйста предлагайте свои условия.
#define F_CPU 1000000L
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
//интервал давления для поддержания нагревателем
#define P_LOW 800 //включать ТЭН при нижней границе давления
#define P_HIGH 830 //выключать ТЭН при верхней границе
#define P_PODACHA 770 //давление открытия клапана подачи
#define P_SPUSK 500 //спуск давления
#define P_VPUSK 500 //спуск вакуума
#define P_VACUM 700 //порог давления в режиме вакума для включения таймера вакумирования
#define TIMER1_DELAY_SEC 10 //задержка таймера 1 (продувка)
#define TIMER2_DELAY_SEC 10 //задержка таймера 2 (стерилизация)
#define TIMER4_DELAY_SEC 10 //задержка таймера 4 (вакуум)
#define e1 PORTD |= 0b00001000
#define e0 PORTD &= 0b11110111
#define rs1 PORTD |= 0b00000100
#define rs0 PORTD &= 0b11111011
bool timer1_start_flag = false; //флаг запуска таймера 1
bool timer2_start_flag = false; //флаг запуска таймера 2
bool timer3_start_flag = false; //флаг запуска таймера 3
bool timer4_start_flag = false; //флаг запуска таймера 4
bool timer5_start_flag = false; //флаг запуска таймера 5
bool timer6_start_flag = false; //флаг запуска таймера 6
int tmrCnt = 0; //счетчик таймера
#define VCC 4.95 // !!!ОБЯЗАТЕЛЬНО!!! задать точное значение питания
//Pt1000 коэффициенты
#define A 0.0039083
#define B -0.0000005775
#define R0 1000
//вычисление напряжения Ut(в Вольтах) на датчике температуры по прочитанному значению ADC (АЦП)
double ADC_to_Ut(int adc_val)
{
return VCC / 1024 * adc_val;
}
//вычисление сопротивления Rt датчика температуры по напряжению Ut на нем
double Ut_to_Rt(double ut)
{
return ut * 1000 / (VCC - ut);
}
//вычисление температуры t(в Целсиях) по сопротивлению датчика Rt
int Rt_to_t(double rt)
{
double d = A * A - 4 * B * (1 - rt / 1000);
return (-A + sqrt(d)) / (2 * B);
}
void sendHalfByte(unsigned char c)
{
c <<= 4;
PORTD &= 0b00001111; //clear 4 high bits
PORTD |= c; //set 4 high bits form c
_delay_us(50);
e1; //lock data
_delay_us(350);
e0;
}
void sendByte(unsigned char c, unsigned char mode)
{
if (mode == 0) rs0;
else rs1;
unsigned char hc = c >> 4;
sendHalfByte(hc);
sendHalfByte(c);
}
//очистка LCD
void lcd_clear(void)
{
sendByte(0b00000001, 0);
_delay_ms(1);
}
//вывод на LCD одного символа в одинарных кавычках ' '
void lcd_sendChar(unsigned char c)
{
sendByte(c, 1);
}
//вывод на LCD строки в двойных кавычках " "
void lcd_sendStr(const char* s)
{
while (*s != '\0')
{
lcd_sendChar(*s++);
}
}
//переместить куроср LCD
void lcd_setPos(unsigned char x, unsigned char y)
{
unsigned char addr = (0x40 * y + x) | 0b10000000;
sendByte(addr, 0);
}
void lcd_init(void)
{
_delay_ms(50);
sendHalfByte(0b00000011);
_delay_ms(5);
sendHalfByte(0b00000011);
_delay_us(120);
sendHalfByte(0b00000011);
_delay_ms(1);
sendHalfByte(0b00000010);
_delay_ms(1);
//sendHalfByte(0b00000010);
//_delay_ms(1);
sendByte(0b00101000, 0);
_delay_ms(1);
sendByte(0b00001100, 0);
_delay_ms(1);
sendByte(0b00000110, 0);
_delay_ms(1);
lcd_clear();
}
//поддержка температуры между заданными t1 и t2, (current - текущее значение)
void set_pressure(int p1, int p2, int current)
{
if (current < p1) // включаем ТЭН, поднимаем температуру
{
PORTC |= (1<<0); //тэн
//PORTC &= ~(1<<2);
//PORTC &= ~(1<<3);
//PORTC &= ~(1<<4);
} else if (current >= p2) // выключаем ТЭН
{
PORTC &= ~(1<<0);
}
}
//управление клапаном подачи пара
void set_podacha(bool f)
{
if (f)
{
PORTC |= (1<<2); //вкл. пар в камеру
} else
{
PORTC &= ~(1<<2); //выкл. пар в камеру
}
}
//управление продувкой
void set_produvka(bool f)
{
if (f)
{
PORTC |= (1<<3); //вкл продувка
} else
{
PORTC &= ~(1<<3); //выкл продувка
}
}
//управление вакуумом
void set_vakum(bool f)
{
if (f)
{
PORTC |= (1<<4); //вкл вакуум
} else
{
PORTC &= ~(1<<4); //выкл вакуум
}
}
//управление впуском после вакуума
void set_vpusk(bool f)
{
if (f)
{
PORTB|= (1<<0); //вкл вакуум
} else
{
PORTB &= ~(1<<0); //выкл вакуум
}
}
int main(void)
{
DDRD = 0b11111100;
PORTD = 0b00000000;
DDRC |= (1<<0) | (1<<2) | (1<<3) | (1<<4);
DDRB |= (1<<0);
DDRC &= ~((1<<1) | (1<<5)); // 0b00100010;
ADCSRA |= (1<<ADEN); // разрешаем работу АЦП
//ADCSRA |= (1<<ADFR); // непрерывное преобразование
ADCSRA &= ~(1<<ADPS2);
ADCSRA |= (1<<ADPS1) | (1<<ADPS0); // частота дискретизации 125 кГц
ADMUX |= (1<<REFS0); // внешний источник 5 В
ADMUX &= ~(1<<REFS1);
ADMUX &= ~(1<<ADLAR); // правостороннее выравнивание
ADMUX &= ~(1<<MUX3) | (1<<MUX2)| (1<<MUX1);
ADMUX |= (1<<MUX0); // задействуем ADC1
ADCSRA |= (1<<ADSC); // запускаем АЦП
//инициализация LCD
lcd_init();
//Вывод HELLO и очистка
lcd_setPos(5, 1);
lcd_sendStr("Hello");
_delay_ms(500);
lcd_clear();
char t_adc[5] ;
/* Replace with your application code */
while (1)
{
lcd_clear();
//вычисляем температуру в одну строку от считанного ADC
int t = Rt_to_t(Ut_to_Rt(ADC_to_Ut(ADC)));
//конвертируем числовое значение t температуры в строку для вывода на LCD
itoa(t, t_adc, 10);
lcd_sendStr(t_adc);
lcd_setPos(0, 1);
//переключаем канал на АЦП5 для датчика давления
ADCSRA &= ~(1<<ADEN); // stop АЦП
ADMUX &= ~(1<<MUX3);
ADMUX |= (1<<MUX2);
ADMUX &= ~(1<<MUX1);
ADMUX |= (1<<MUX0); // задействуем ADC5
ADCSRA |= (1<<ADEN); // разрешаем работу АЦП
ADCSRA |= (1<<ADSC); // запускаем АЦП
_delay_ms(1); // пропускаем первые несколько конверсий
int pressure = ADC; //Cчитываем ADC 5канал - давление
itoa(pressure, t_adc, 10);
lcd_sendStr(t_adc);
if (!timer1_start_flag) //если таймер 1 не запущен
{
set_pressure(P_LOW, P_HIGH, pressure); //авторегулировка давленияв заданном интервале
if (pressure >= P_PODACHA) set_podacha(true); //подача пара
if (pressure >= P_HIGH)
{
set_produvka(true);
timer1_start_flag = true; //запуск таймера 1
}
} else if (!timer2_start_flag) //если таймер 1 запущен, а таймер 2 еще нет
{
set_pressure(P_LOW, P_HIGH, pressure); //авторегулировка давленияв заданном интервале
if (tmrCnt >= TIMER1_DELAY_SEC) //таймер 1 истек
{
set_produvka(false);
timer2_start_flag = true; //запуск таймера 2
tmrCnt = 0;
} else {
tmrCnt++;
itoa(tmrCnt, t_adc, 10);//отображаем таймер на дисплей в секундах
lcd_sendStr(" Produv ");
lcd_sendStr(t_adc);
}
}
if (timer2_start_flag && (!timer3_start_flag)) //если таймер 2 запущен, а таймер 3 еще нет
{
set_pressure(P_LOW, P_HIGH, pressure); //авторегулировка давленияв заданном интервале
if (tmrCnt >= TIMER2_DELAY_SEC)
{
PORTC &= ~(1<<0); //выкл ТЭН
set_podacha(false); //выкл клапан подачи пара
set_produvka(true); //открыть продувку
tmrCnt = 0;
timer3_start_flag = true;
} else {
itoa(tmrCnt, t_adc, 10);//отображаем таймер на дисплей в секундах
lcd_sendStr(" Steril ");
lcd_sendStr(t_adc);
tmrCnt++;
}
}
if (timer3_start_flag && (!timer4_start_flag)) //если таймер 3 запущен, а таймер 4 еще нет (на самом деле это не совсем таймер, а ожидание выравнивания давления)
{
if (pressure > P_SPUSK)
{
lcd_sendStr(" Spusk ");
} else
{
set_produvka(false); //выкл. продувку
set_vakum(true); //вкл. вакуум
tmrCnt = 0;
timer4_start_flag = true;
}
}
if (timer4_start_flag && (!timer5_start_flag)) //если таймер 4 запущен, а таймер 5 еще нет
{
if (tmrCnt >= TIMER4_DELAY_SEC)
{
set_vakum(false);
set_vpusk(true);
tmrCnt = 0;
timer5_start_flag = true;
} else if (pressure > P_VACUM)
{
itoa(tmrCnt, t_adc, 10);//отображаем таймер на дисплей в секундах
lcd_sendStr(" Vacum ");
lcd_sendStr(t_adc);
tmrCnt++;
}
}
if (timer5_start_flag) //если последний таймер 5 запущен (на самом деле это не совсем таймер, а ожидание выравнивания давления)
{
if (pressure > P_VPUSK)
{
lcd_sendStr(" Vpusk ");
} else
{
set_vpusk(false);
lcd_clear();
lcd_setPos(3, 0);
lcd_sendStr("Okoncheno");
_delay_ms(250);
while(1);
}
}
//переключаем канал на АЦП1
ADCSRA &= ~(1<<ADEN); // stop АЦП
ADMUX &= ~((1<<MUX3) | (1<<MUX2) | (1<<MUX1));
ADMUX |= (1<<MUX0); // задействуем ADC1
ADCSRA |= (1<<ADEN); // разрешаем работу АЦП
ADCSRA |= (1<<ADSC); // запускаем АЦП
_delay_ms(970); //задержка на каждой итерации, чтобы с учетом остального кода была одна секунда на каждый круг, тогда один тик таймера это одна секунда
} }