PLC와 아두이노 그리고 온도 센서를 이용하여 램프 점등
우선은 전에 만들어둔
ArduinoUno(Atmega328P), LM35(온도센서)를 이용해 LCD에 Text 나타내기
와
PCB 실습_220V를 5V로 전압 감하
를 이용하여 만들었다.
2가지 방식으로 작동하도록 만들었다.
1) 자동 : 온도 센서의 일정한 값에 따라 Lamp의 불이 들어오게 만들었다.
2) 수동 : 수동 모드로 전환하는 스위치를 눌러 자동 동작은 정지하고 수동으로 스위치 조작하며 one button 방식으로 설정하였다.
글로파에 올릴 프로그램은 GMWIN에서 작성하였다.
작성 후 접속+쓰기+모드전환+모니터시작 으로 연결과 업로드를 동시에 실행하였다.
아두이노의 전원 공급은 5V로 전압 감하된 전원을 사용한다.
➢Atmel7.0을 이용하여 아두이노에 업로드한 코드
/*
* Atmega328p_PLC_1213.c
*
* Created: 2018-12-13 오후 2:22:24
* Author : USER
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include "lcd.h"
// LCD.h 시작
// LCD.h 끝
#define MAX_LCD_STRING 0x40
#define SINGLE_MODE 0
#define FREE_MODE 1
#define PRESSED 0
#define RELEASED 1
volatile int adc_rq=0, adc_result=0;
volatile unsigned int mode = SINGLE_MODE;
//volatile float V=0;
ISR(ADC_vect)
{ adc_result = ADC;
adc_rq = 0;
}
void ADC_init(void)
{
// ADC 활성화, ADC 인터럽트 활성화, 프리스케일러 CPU 분주비=64
ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADATE | 6;
ADMUX |= 1<<REFS0;
}
enum {MODE_CONFIRM, ADC_START, ADC_DONE} state=MODE_CONFIRM;
//////////////////////////////////////////////////////////////
int main(void)
{
char lcd_string[2][MAX_LCD_STRING];
ADC_init();
LCD_init();
sprintf(lcd_string[0], "Temp=");
sprintf(lcd_string[1], "ADC result= ");
LCD_str_write(0, 0, lcd_string[0]);
LCD_str_write(1, 0, lcd_string[1]);
//sei(); // start global interrupt
ADCSRA |= 1<<ADSC;
DDRB |= 1<<PB3 | 1<<PB4 | 1<<PB5;
PORTB |= 1<<PB3 | 1<<PB4 | 1<<PB5;
DDRC &= 0<<PC5;
DDRC |= 1<<PC4;
PORTC |= 1<<PC5;
sei();
while(1){
// LCD에 float설정으로 실수 표현
float V;
V = (float)ADC*5/1023;
while(adc_rq); // ADC가 종료되기를 기다림
if(!(PINC & 1<<PC5)){
PORTC = PORTC | 1<<PC4;
}
else{
PORTC = PORTC & ~(1<<PC4);
}
//PB3, 4, 5
if(55<=adc_result && adc_result<60){
PORTB = 1<<PB3;
}
else if(60<=adc_result && adc_result<65){
PORTB = 1<<PB4;
}
else if(65<=adc_result){
PORTB = 1<<PB5;
}
else if(adc_result<55){
PORTB = 0;//<<PB3 | 0<<PB4 | 0<<PB5;
}
sprintf(lcd_string[0], "%4.1f[`C]", V*100); // 실수로 표현
// sprintf(lcd_string[0], "%-d.%02d[V]", V/100, V%100); // long형 정수로 표현
void LCD_init(void);
LCD_str_write(0, 6, lcd_string[0]);
sprintf(lcd_string[1], "%-4d ", ADC);
LCD_str_write(1, 12, lcd_string[1]);
_delay_ms(500);
}
return 0;
}
➢실제 기판과 연결하기전 브레드 보드에서 온도 센서 작동을 LED로 점검
글로파의 입력은 24V를 이용하기에 릴레이를 사용하여 서로 연결해 주었으며, 자동/수동 전환 스위치도 아두이노에서 감지를 하면 릴레이를 이용하여 작동하게 만들어 두었다.
2) 수동 : 수동 모드로 전환하는 스위치를 눌러 자동 동작은 정지하고 수동으로 스위치 조작하며 one button 방식으로 설정하였다.
글로파에 올릴 프로그램은 GMWIN에서 작성하였다.
작성 후 접속+쓰기+모드전환+모니터시작 으로 연결과 업로드를 동시에 실행하였다.
아두이노의 전원 공급은 5V로 전압 감하된 전원을 사용한다.
➢Atmel7.0을 이용하여 아두이노에 업로드한 코드
/*
* Atmega328p_PLC_1213.c
*
* Created: 2018-12-13 오후 2:22:24
* Author : USER
*/
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <util/delay.h>
#include "lcd.h"
// LCD.h 시작
// LCD.h 끝
#define MAX_LCD_STRING 0x40
#define SINGLE_MODE 0
#define FREE_MODE 1
#define PRESSED 0
#define RELEASED 1
volatile int adc_rq=0, adc_result=0;
volatile unsigned int mode = SINGLE_MODE;
//volatile float V=0;
ISR(ADC_vect)
{ adc_result = ADC;
adc_rq = 0;
}
void ADC_init(void)
{
// ADC 활성화, ADC 인터럽트 활성화, 프리스케일러 CPU 분주비=64
ADCSRA |= 1<<ADEN | 1<<ADIE | 1<<ADATE | 6;
ADMUX |= 1<<REFS0;
}
enum {MODE_CONFIRM, ADC_START, ADC_DONE} state=MODE_CONFIRM;
//////////////////////////////////////////////////////////////
int main(void)
{
char lcd_string[2][MAX_LCD_STRING];
ADC_init();
LCD_init();
sprintf(lcd_string[0], "Temp=");
sprintf(lcd_string[1], "ADC result= ");
LCD_str_write(0, 0, lcd_string[0]);
LCD_str_write(1, 0, lcd_string[1]);
//sei(); // start global interrupt
ADCSRA |= 1<<ADSC;
DDRB |= 1<<PB3 | 1<<PB4 | 1<<PB5;
PORTB |= 1<<PB3 | 1<<PB4 | 1<<PB5;
DDRC &= 0<<PC5;
DDRC |= 1<<PC4;
PORTC |= 1<<PC5;
sei();
while(1){
// LCD에 float설정으로 실수 표현
float V;
V = (float)ADC*5/1023;
while(adc_rq); // ADC가 종료되기를 기다림
if(!(PINC & 1<<PC5)){
PORTC = PORTC | 1<<PC4;
}
else{
PORTC = PORTC & ~(1<<PC4);
}
//PB3, 4, 5
if(55<=adc_result && adc_result<60){
PORTB = 1<<PB3;
}
else if(60<=adc_result && adc_result<65){
PORTB = 1<<PB4;
}
else if(65<=adc_result){
PORTB = 1<<PB5;
}
else if(adc_result<55){
PORTB = 0;//<<PB3 | 0<<PB4 | 0<<PB5;
}
sprintf(lcd_string[0], "%4.1f[`C]", V*100); // 실수로 표현
// sprintf(lcd_string[0], "%-d.%02d[V]", V/100, V%100); // long형 정수로 표현
void LCD_init(void);
LCD_str_write(0, 6, lcd_string[0]);
sprintf(lcd_string[1], "%-4d ", ADC);
LCD_str_write(1, 12, lcd_string[1]);
_delay_ms(500);
}
return 0;
}
➢실제 기판과 연결하기전 브레드 보드에서 온도 센서 작동을 LED로 점검
글로파의 입력은 24V를 이용하기에 릴레이를 사용하여 서로 연결해 주었으며, 자동/수동 전환 스위치도 아두이노에서 감지를 하면 릴레이를 이용하여 작동하게 만들어 두었다.
댓글
댓글 쓰기