Dawno temu postanowiłem wkonać samodzielnie sterownik do kolby Solomon SL1. Zakupiłem więc kolbę i tak przeleżała sobie kilka ładnych lat. Ostatnio postanowiłem zrobić z niej użytek. Po przejrzeniu kilku projektów w internecie powstał mój - podobny do innych.

Założenia:
* Regulacja nastawionej temperatury.
* Nastawianie dokonywane przyciskami lub koderem obrotowym.
* Wyświetlanie statusu na wyswietlaczu LCD lub LED - ostatecznie zostal uzyty LCD 2linie x 8znaków.
* Kolba lutownicza z termoparą. Solomon posiada termoparę typu K. Opis można znaleźć tu: http://www.termoaparatura.com.pl/index.php?go=1457
Zasilacz
Użyłem transformatora TS40/47, który akurat miałem pod ręką. Posiada on 4 uzwojenia po 10v, które wykorzystałem do wykonania prostowników 2 połówkowych dla napięć +24v, +5v, -5v (5V stabilizowane). Pod obciążeniem napięcie zasilania grzałki lutownicy utrzymuje się w okolicach 24v.
Sterownik
Do sterowania zasilaniem grzałki wykorzystany został procesor Atmega8. Zadawnie temperatury odbywa się za pomocą 2 przycisków, z krokiem co 10 stopni. Napięcie z termopary wzmacniane jest 151x za pomocą wzmacniacza OP07C, ewentualne zakłócenia filtrowane są za pomocą układów całkujących na jego wejściu i wyjściu. Ze wzmacniacza sygnał kierowany jest do wewnętrzenego przetwornika ADC procesora. Przetwornik pracuje w trybie 10bitowym, pomiar dokonywany jest w stanie uspienia procesora i przy wyłączonym przetworniku PWM dla zmniejszenia zakłoceń i zwiekszenia precyzji pomiaru. Odczytana wartość dzielona jest przez 2.4, co w wyniku daje wartość temperatury w stopniach Celsjusza. W zależności od róznicy między temperaturą zadaną a odczytaną dostarczana jest różna moc do grzałki - przedstawia to poniższa 'tabelka': (dt = temperatura zadana - temperatura odczytana)
dt PWM [%]
>3 100
3 80
2 60
1 40
0 20
Jak widać, regulacja jest skokowa, z dokładnością do jednego stopnia. W połączeniu z odczytem temperatury 3x na sekudę daje to wystarczającą dokładność regulacji. Maksymalna mozliwa do ustawienia temperatura to 420 stopni - wynika z napięć termopary, wzmocnienia stopnia wejściowego i napięcia odniesienia przetwornika ADC. Zakres ten można rozszerzyć zmniejszając wzmocnienie stopnia wejściowego oraz współczynnnik podziału odczytu ADC.
Układ współpracuje z termoelementem typu K, dla innych typów należy dostosować wzmocnienie stopnia wejściowego i zmodyfikować program.
Schemat

Złącza:
LCD słyży do podłączenia wyświetlacza ze standardowym sterownikiem HD.
IMP - podłączenie klawiatury lub kodera obrotowego oraz diod LED sygnalizujących np. grzanie (nie używane).
ISP - złącze programatora w stadardzie KANDA.
Program
[code]
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "LCD/lcd44780.h"
volatile int temp_read=0;
volatile int temp_set=0;
int pwm=0;
//inicjalizacja ADC
void initADC()
{
ADMUX = (1<<REFS0)|(1<<REFS1); //internal VREF = 2.65v
ADMUX |= 0x05; //wejscie ADC5
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE); //enable + INT + start str.207
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //prescaler = 128 str.208
}
//ustawienie obsługo przerwań
void initINT()
{
// przerwania na INT0 oraz INT1 wyzwalane przez zbocze opadające
MCUCR = (1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10);
GICR |= (1<<INT0)|(1<<INT1); //wlaczenie zewn. INT0, INT1
GIFR=0xC0; //wyczyszczenie flag przerwań INT0, INT1
sei();
}
//włączenie PWM z zadanym wypełnieniem
void setPWM(int value)
{
DDRB |= (1<<PB2);
if(value<=0)
{
PORTB &= ~(1<<PB2); //0% bez uzycia PWM
return;
}
if(value>=100) //100% bez uzycia PWM
{
PORTB |= (1<<PB2);
return;
}
TCCR1A |= (1<<WGM10)|(1<<WGM12);//tryb FastPWM 8bit, str.98
TCCR1A |= (1<<COM1B1); //Set OC1A/OC1B on Compare Match, clear OC1A/OC1B at BOTTOM, (inverting mode), str.97
TCCR1B |= (1<<CS10); //No prescaling, str.100
OCR1B=value * 2.55; // % -> 0..255
}
//zatrzymanie PWM, zero na wyjście
void stopPWM()
{
PORTB &= ~(1<<PB2);
TCCR1A = 0;
TCCR1B = 0;
}
void refreshDisplay()
{
lcd_cls();
lcd_str("s");
lcd_int(temp_set);
lcd_locate(1,0);
lcd_str("r");
lcd_int(temp_read);
lcd_locate(0,5);
lcd_str("PWM");
lcd_locate(1,5);
lcd_int(pwm);
}
int main(void)
{
lcd_init();
lcd_str("SOLOMON1");
lcd_locate(1,0);
lcd_str("suszig");
_delay_ms(2000);
initADC();
initINT();
int dt=0;
while(1)
{
stopPWM();
_delay_ms(10);
ADCSRA |= (1<<ADSC); //start pomiaru
MCUCR|= (1<<SM0)|(1<<SE); //w trybie uśpienia
sleep_cpu();
dt = temp_set - temp_read;
if(dt>3)
pwm=100;
else if (dt<0)
pwm=0;
else
{
switch (dt)
{ //zamiast obliczania
case 0: pwm = 20; break;
case 1: pwm = 40; break;
case 2: pwm = 60; break;
case 3: pwm = 80; break;
}
}
refreshDisplay();
setPWM(pwm);
_delay_ms(333);
}
}
ISR( INT0_vect )
{
temp_set+=10;
if(temp_set>400)
temp_set=400;
}
ISR( INT1_vect )
{
temp_set-=10;
if(temp_set<=0)
temp_set=0;
}
ISR(ADC_vect)
{
temp_read = ADC /2.45; //temp w stopniach, wzmocnienie napiecia termopry typu K x151
}
[/code]
W planie mam wymianę przycisków na koder obrotowy.
Koszt rozłożony w długim czasie, zdecydowanie poniżej 100zł.

Założenia:
* Regulacja nastawionej temperatury.
* Nastawianie dokonywane przyciskami lub koderem obrotowym.
* Wyświetlanie statusu na wyswietlaczu LCD lub LED - ostatecznie zostal uzyty LCD 2linie x 8znaków.
* Kolba lutownicza z termoparą. Solomon posiada termoparę typu K. Opis można znaleźć tu: http://www.termoaparatura.com.pl/index.php?go=1457
Zasilacz
Użyłem transformatora TS40/47, który akurat miałem pod ręką. Posiada on 4 uzwojenia po 10v, które wykorzystałem do wykonania prostowników 2 połówkowych dla napięć +24v, +5v, -5v (5V stabilizowane). Pod obciążeniem napięcie zasilania grzałki lutownicy utrzymuje się w okolicach 24v.
Sterownik
Do sterowania zasilaniem grzałki wykorzystany został procesor Atmega8. Zadawnie temperatury odbywa się za pomocą 2 przycisków, z krokiem co 10 stopni. Napięcie z termopary wzmacniane jest 151x za pomocą wzmacniacza OP07C, ewentualne zakłócenia filtrowane są za pomocą układów całkujących na jego wejściu i wyjściu. Ze wzmacniacza sygnał kierowany jest do wewnętrzenego przetwornika ADC procesora. Przetwornik pracuje w trybie 10bitowym, pomiar dokonywany jest w stanie uspienia procesora i przy wyłączonym przetworniku PWM dla zmniejszenia zakłoceń i zwiekszenia precyzji pomiaru. Odczytana wartość dzielona jest przez 2.4, co w wyniku daje wartość temperatury w stopniach Celsjusza. W zależności od róznicy między temperaturą zadaną a odczytaną dostarczana jest różna moc do grzałki - przedstawia to poniższa 'tabelka': (dt = temperatura zadana - temperatura odczytana)
dt PWM [%]
>3 100
3 80
2 60
1 40
0 20
Jak widać, regulacja jest skokowa, z dokładnością do jednego stopnia. W połączeniu z odczytem temperatury 3x na sekudę daje to wystarczającą dokładność regulacji. Maksymalna mozliwa do ustawienia temperatura to 420 stopni - wynika z napięć termopary, wzmocnienia stopnia wejściowego i napięcia odniesienia przetwornika ADC. Zakres ten można rozszerzyć zmniejszając wzmocnienie stopnia wejściowego oraz współczynnnik podziału odczytu ADC.
Układ współpracuje z termoelementem typu K, dla innych typów należy dostosować wzmocnienie stopnia wejściowego i zmodyfikować program.
Schemat

Złącza:
LCD słyży do podłączenia wyświetlacza ze standardowym sterownikiem HD.
IMP - podłączenie klawiatury lub kodera obrotowego oraz diod LED sygnalizujących np. grzanie (nie używane).
ISP - złącze programatora w stadardzie KANDA.
Program
[code]
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include "LCD/lcd44780.h"
volatile int temp_read=0;
volatile int temp_set=0;
int pwm=0;
//inicjalizacja ADC
void initADC()
{
ADMUX = (1<<REFS0)|(1<<REFS1); //internal VREF = 2.65v
ADMUX |= 0x05; //wejscie ADC5
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE); //enable + INT + start str.207
ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); //prescaler = 128 str.208
}
//ustawienie obsługo przerwań
void initINT()
{
// przerwania na INT0 oraz INT1 wyzwalane przez zbocze opadające
MCUCR = (1<<ISC01)|(0<<ISC00)|(1<<ISC11)|(0<<ISC10);
GICR |= (1<<INT0)|(1<<INT1); //wlaczenie zewn. INT0, INT1
GIFR=0xC0; //wyczyszczenie flag przerwań INT0, INT1
sei();
}
//włączenie PWM z zadanym wypełnieniem
void setPWM(int value)
{
DDRB |= (1<<PB2);
if(value<=0)
{
PORTB &= ~(1<<PB2); //0% bez uzycia PWM
return;
}
if(value>=100) //100% bez uzycia PWM
{
PORTB |= (1<<PB2);
return;
}
TCCR1A |= (1<<WGM10)|(1<<WGM12);//tryb FastPWM 8bit, str.98
TCCR1A |= (1<<COM1B1); //Set OC1A/OC1B on Compare Match, clear OC1A/OC1B at BOTTOM, (inverting mode), str.97
TCCR1B |= (1<<CS10); //No prescaling, str.100
OCR1B=value * 2.55; // % -> 0..255
}
//zatrzymanie PWM, zero na wyjście
void stopPWM()
{
PORTB &= ~(1<<PB2);
TCCR1A = 0;
TCCR1B = 0;
}
void refreshDisplay()
{
lcd_cls();
lcd_str("s");
lcd_int(temp_set);
lcd_locate(1,0);
lcd_str("r");
lcd_int(temp_read);
lcd_locate(0,5);
lcd_str("PWM");
lcd_locate(1,5);
lcd_int(pwm);
}
int main(void)
{
lcd_init();
lcd_str("SOLOMON1");
lcd_locate(1,0);
lcd_str("suszig");
_delay_ms(2000);
initADC();
initINT();
int dt=0;
while(1)
{
stopPWM();
_delay_ms(10);
ADCSRA |= (1<<ADSC); //start pomiaru
MCUCR|= (1<<SM0)|(1<<SE); //w trybie uśpienia
sleep_cpu();
dt = temp_set - temp_read;
if(dt>3)
pwm=100;
else if (dt<0)
pwm=0;
else
{
switch (dt)
{ //zamiast obliczania
case 0: pwm = 20; break;
case 1: pwm = 40; break;
case 2: pwm = 60; break;
case 3: pwm = 80; break;
}
}
refreshDisplay();
setPWM(pwm);
_delay_ms(333);
}
}
ISR( INT0_vect )
{
temp_set+=10;
if(temp_set>400)
temp_set=400;
}
ISR( INT1_vect )
{
temp_set-=10;
if(temp_set<=0)
temp_set=0;
}
ISR(ADC_vect)
{
temp_read = ADC /2.45; //temp w stopniach, wzmocnienie napiecia termopry typu K x151
}
[/code]
W planie mam wymianę przycisków na koder obrotowy.
Koszt rozłożony w długim czasie, zdecydowanie poniżej 100zł.
Skomentuj