Regulator for soldering iron on Atmega8

    Amateur radio is my hobby, so there is no permanent workplace. Usually, you have to take all the pridendals from the cabinet every time, lay them out on a table or on the floor, and then remove them every time. At the same time, the socket in the work zone is usually one, it is always lazy to make an extension cord, but it also needs to be stored somewhere. And it strains with one socket after conducting a test of the device that is powered from the outlet, then wait for about 5 minutes again until the soldering iron gets warm. After reading the Internet I decided that I need a soldering station, but spend 5-10 tr. For the sake of passion, I was not ready yet. The solution is a homemade floating station.
    Who cares what happened - I ask under the cat.


    For a start, I bought such a soldering
    image

    iron for 250 rubles for Ali, so- so but for the house it would go, I had to really replace the sting right away, since now they have a choice of 100 rubles each.
    Power supply bought ready for 60W 24 volts.

    Schemes will not be again, but on the signet signed all face values.
    image
    Lay-in board.

    The goal was to assemble everything on one board and as compact as possible. Stabilizer power supply and field installed lying down. The device is powered by 5 volts and as it turned out, 7805 heats up to 70-80 degrees, put a small radiator, the field heater does not heat at all.

    I made the plate by LUT, it turned out almost perfectly:
    Before the dressing:
    image
    And after the assembly: The
    image

    ready-made regulator in the assembly looks, in my opinion, even pretty
    image

    If the connector for the programmer does not install, then the board without a single jumper.
    As you can see, and the details of the minimum, even the minimum resistors, only on the general findings of the indicator.
    The indicator is red with large numbers, control of the encoder (valcoder).
    The first inclusion:
    image

    From the classic PID refused, made some of its similarity, the goal - the minimum heating time.
    If you press the encoder shaft and hold it for 3 seconds, you can adjust the display mode, the tuning step and the temperature adjustment (thermocouples are all different).
    I took a video on the phone, the quality is not very good, but the principle of operation is clear


    The body, the body ... and here a great thought was born.
    image

    And when it’s time to put it in the closet:
    image

    Source codes for those who want to repeat.
    Download project for atmel studio
    Project code
    #include<avr/io.h>#include<avr/interrupt.h>#include<avr/eeprom.h>unsignedchar display_on, registr, butt1,butt2,butt3, butt3s, zamer,rezhim,mode,param,params, edit, redit, blink, wait2, wait3, wait5, wait6, wait7, rdisp, encoder_r, encoder_l, right, left, prewmode;
    unsignedchar ind[4],tempvar, tempmem;
    float measureint, voltage_ADC,tmp;
    unsignedint stop_h, stop_m, pwm_d, measure, pmeasure;
    int pwm,tempch;
    //unsigned int voltage_ADC;unsignedchar param1[10]; 
    unsignedchar param1eeprom[10] EEMEM;
    uint16_t tempset,measure; uint16_t tem EEMEM;
    unsignedchar pwm_m[455] EEMEM;
    ISR (TIMER0_OVF_vect)
    {
    		 if(display_on==1)  
    			 {
    				 PORTB |= (1 << PB6); PORTD |= (1 << PD7); PORTD |= (1 << PD3); PORTC |= (1 << PC2);
    				 PORTB &=~ (1 << PB0); //1
    				 PORTC &=~ (1 << PC1); //2
    				 PORTD &=~ (1 << PD4); //3
    				 PORTD &=~ (1 << PD2); //4
    				 PORTD &=~ (1 << PD5); //5
    				 PORTB &=~ (1 << PB7); //6
    				 PORTD &=~ (1 << PD6); //7
    			 }
    		 if(display_on==37)
    			 {
    				if(ind[registr]==0 || ind[registr]==6 || ind[registr]==9) {display_on=display_on+20;} //6 сегментовif(ind[registr]==2 || ind[registr]==3 || ind[registr]==5 || ind[registr]=='P') {display_on=display_on+25;} //5 сегментовif(ind[registr]==4 || ind[registr]=='g') {display_on=display_on+35;} //4 сегмента	if(ind[registr]==7) {display_on=display_on+40;} // 3 сегментаif(ind[registr]==1) {display_on=display_on+45;} //2 сегментаif(ind[registr]=='-') {display_on=display_on+50;} //2 сегментаif(registr==0) { PORTB &=~ (1 << PB6);}
    				 if(registr==1) { PORTD &=~ (1 << PD3);}
    				 if(registr==2) { PORTC &=~ (1 << PC2);}
    				 if(registr==3) { PORTD &=~ (1 << PD7);}
    					 if (ind[registr]==0) {PORTB |= (1 << PB0);PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD5);PORTB |= (1 << PB7);}//0if (ind[registr]==1) {PORTD |= (1 << PD2);PORTD |= (1 << PD5);}//1if (ind[registr]==2) {PORTB |= (1 << PB0);PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//2if (ind[registr]==3) {PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD5);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//3if (ind[registr]==4) {PORTC |= (1 << PC1);PORTD |= (1 << PD2);PORTD |= (1 << PD5);PORTD |= (1 << PD6);}//4if (ind[registr]==5) {PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD5);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//5if (ind[registr]==6) {PORTB |= (1 << PB0);PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD5);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//6if (ind[registr]==7) {PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD5);}//7if (ind[registr]==8) {PORTB |= (1 << PB0);PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD5);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//8if (ind[registr]==9) {PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD5);PORTB |= (1 << PB7); PORTD |= (1 << PD6);}//9if (ind[registr]=='P') {PORTB |= (1 << PB0);PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD2);PORTD |= (1 << PD6);}//Pif (ind[registr]=='g') {PORTC |= (1 << PC1);PORTD |= (1 << PD4);PORTD |= (1 << PD2); PORTD |= (1 << PD6);}//g	if (ind[registr]=='-') {PORTD |= (1 << PD6);}//- if (ind[registr]=='F') {PORTB |= (1 << PB0);PORTC |= (1 << PC1);PORTD |= (1 << PD4); PORTD |= (1 << PD6);}//Fif (ind[registr]=='n') {PORTB |= (1 << PB0);PORTD |= (1 << PD5); PORTD |= (1 << PD6);}//n	 
    				 registr++;
    				 if (registr>3){registr=0;}
    			 }
    			 display_on++;
    			 if (display_on>100){display_on=1;blink++; if(blink>250){blink=0;} ADCSR |= (1<<ADSC);}
    				 if(blink==250){wait2++; if(wait2>250){wait2=0;}}
    				  if(wait2==250){wait3++; if(wait3>250){wait3=251;}; butt3s++; if(butt3s>250){butt3s=251;}; wait5++;wait6++;}	 
    				   if(wait3==3 && mode==1){mode=0;}
    					   if(wait5==20){wait5=0;}
    						   if(wait5==51){wait5=0;}
    							   if(wait5==50){wait6++; if(wait6==250){wait6=0;};if(wait6==param1[3]){rezhim=0;}}
    }
    voidinit_pwm(void){
    	TCCR1A|=(1<<COM1A0);
    	TCCR1A|=(1<<COM1A1);
    	TCCR1B|=(1<<CS10);
    	//TCCR1A|=(1<<WGM10);
    	TCCR1A|=(1<<WGM11); 
    	//TCCR1B|=(1<<WGM12);
    	TCCR1B|=(1<<WGM13);
    	//Установка начальных значений счетчиков
    	OCR1A=27000;
    	//OCR1B=10000; //Выключен 0 от 200/170 до 250/215
    	ICR1=27000;
    }
    ISR (ADC_vect)//прерывание по завершению преобразования АЦП
    {
    	voltage_ADC = voltage_ADC+ADCW;//считываем значение АЦ преобразованияif (zamer==100) 
    	 {
    	   measureint=voltage_ADC/zamer;
    	   measure=measureint*param1[2]/100;
    	   if(rezhim==1)
    	    {   
    	     if(mode==0)
    		  {
    			if(param1[0]>0) {ind[0]=measure/100;ind[1]=measure%100/10;ind[2]=measure%10;ind[3]='g';}
    			if(param1[0]==0) 
    			    {
    				  if(tempset<100){ind[0]=-1;} else {ind[0]=tempset/100;}
    					 if(tempset<10) {ind[1]=-1;} else {ind[1]=tempset%100/10;}
    						 ind[2]=tempset%10;ind[3]='g';
    				}
    	      }
    		 if(mode==1)
    		    {  
    			  if(blink<170)
    			   {if(tempset<100){ind[0]=-1;} else {ind[0]=tempset/100;}
    			    if(tempset<10) {ind[1]=-1;} else {ind[1]=tempset%100/10;}
    			    ind[2]=tempset%10;ind[3]='g';
    			   }
    				  if(blink>170){ind[0]=-1;ind[1]=-1;ind[2]=-1;ind[3]=-1;}
    			}
    	    }
    	  if(tempmem==0)
    	    {
    	         if(wait5==10)//5=10 секунд
    	         {
    		          if(tempch==0 && tempset==measure && eeprom_read_byte(&pwm_m[tempset])!=pwm)
    		          {eeprom_write_byte(&pwm_m[tempset],pwm); tempmem=1; ind[0]='g';ind[1]='g';ind[2]='g';}
    				 if(tempset!=measure) 
    		         {
    			         pwm_d=tempset-measure;
    			         pwm=pwm+pwm_d;
    		         }
    		         wait5=0;tempch=0;
    		     }
    		    if(pmeasure<measure && tempset<measure) //температура больше установленно и наблюдается рост
    			  {
    				pwm_d=measure-tempset; tempch++;
    				pwm=pwm-pwm_d;
    				pmeasure=measure;
    			  }
    			  if(pmeasure>measure && tempset>measure) //температура меньше установленно и наблюдается снижение
    			  {
    				pwm_d=tempset-measure; tempch++;
    				pwm=pwm+pwm_d*measure/100; 
    				pmeasure=measure;
    			  }	
    		  }
    		 if(wait5==10 && tempmem==1)//5=10 секунд
    		   {  
    			 if(tempset<measure){pwm=pwm-1;}
    			 if(tempset>measure){pwm=pwm+1;}
    			 if(tempset==measure && eeprom_read_byte(&pwm_m[tempset])>pwm && eeprom_read_byte(&pwm_m[tempset])-pwm>5){eeprom_write_byte(&pwm_m[tempset],pwm);}
    			 if(tempset==measure && eeprom_read_byte(&pwm_m[tempset])>pwm && eeprom_read_byte(&pwm_m[tempset])-pwm>5){eeprom_write_byte(&pwm_m[tempset],pwm);}	 
    			 wait5=0;
    			 if(tempset==measure && tempmem==1 && (int)(voltage_ADC*param1[2]/100)%zamer<50){tmp=tmp-10;}
    			 if(tempset==measure && tempmem==1 && (int)(voltage_ADC*param1[2]/100)%zamer>50){tmp=tmp+10;}
    		   }	
    		if(pwm>250){pwm=250;} if(pwm<0){pwm=0;}
    		if(tempset-10>measure && tempmem==1){OCR1A=0;wait5=0;wait6=0;} else {OCR1A=27000+tmp-pwm*108;}   
    	  voltage_ADC=0;zamer=0;		
    	}
    	zamer++; 
    	if (rezhim!=1) {OCR1A=27000;} 
    		if (measure>480) {OCR1A=27000;rezhim=0;OCR1A=27000;}
    	//ADCSR |= (1<<ADSC);//запускаем очередное преобразование
    }
    //Основная программаintmain(void){
    TIMSK |= (1 << TOIE0); // Разрешаем прерывание по переполнению Т2
    TCCR0|=(0<<CS02)|(1<<CS00);
    init_pwm(); //Инициализация ШИМ каналов//ads
    ADMUX|= (1<<REFS0); //ВНУТРЕННЕЕ ОПОРНОЕ
    ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
    sei(); // Глобально разрешаем прерывания
    PORTB=0b00000000; PORTC=0b00101000; PORTD=0b00000001;//Включаем подтягивающий резистор
    DDRB=0b11111111; DDRC=0b11010110; DDRD=0b11111110;
    butt1=0;butt2=0;butt3=0;rezhim=0;mode=0;params=0;edit=0;redit=0;blink=0;tempmem=0;tempch=0;
    encoder_l=40; encoder_r=0; right=0; left=0;butt3s=0;wait3=0;wait2=0;mode=0;prewmode=0;pwm_d=0;
    tempset = eeprom_read_word(&tem); if(tempset>500){tempset=100;}	
    param1[0] = eeprom_read_byte(¶m1eeprom[0]); if(param1[0]>1){param1[1]=1;}
    param1[1] = eeprom_read_byte(¶m1eeprom[1]); if(param1[1]>10){param1[1]=5;}	
    param1[2] = eeprom_read_byte(¶m1eeprom[2]); if(param1[2]>250){param1[2]=75;}
    param1[3] = eeprom_read_byte(¶m1eeprom[3]); if(param1[3]>250){param1[3]=10;}
    pwm=eeprom_read_byte(&pwm_m[tempset]); if (pwm<255){tempmem=1;}
    while (1) //Вечный цикл
    {
    if(tempset<100){tempset=100;}	if(tempset>450){tempset=450;}
    //кнопка энкодераif ((PINC&(1<<PC5))==0x00){butt1++; if(butt1>200){butt1=201;}} else {butt1=0;}
     if(butt1==200 && rezhim==0){butt3s=0; rezhim=1; butt1=201;}
     if(butt1==200 && rezhim==1){butt3s=0; rezhim=0; butt1=201;}
     if(butt1==200) {butt3s=0;}
    	if (butt1==201 && butt3s==2 && rezhim!=2){rezhim=2;butt3s=10;}
    	if (butt1==201 && butt3s==2 && rezhim==2){rezhim=0;butt3s=10;}	
    //Поворот энкодера	if ((PIND&(1<<PD0))==0x00){butt2++; if(butt2>encoder_l){butt2=encoder_l+1;}} else {butt2=0;}
    if ((PINC&(1<<PC3))==0x00){butt3++; if(butt3>encoder_l){butt3=encoder_l+1;}} else {butt3=0;}
    if(right==1 || left==1){right=0; left=0;}
    if(encoder_r==0) 
      {
    	  if(butt2==encoder_l+1 && butt3==encoder_l) {encoder_r=encoder_l*5;mode=1;wait3=0;right=1;}
    	  if(butt3==encoder_l+1 && butt2==encoder_l) {encoder_r=encoder_l*5;mode=1;wait3=0;left=1;}
      }
    if(encoder_r==0){encoder_r=1;} encoder_r--;
    if(mode!=prewmode){prewmode=mode; eeprom_write_word(&tem, tempset);} 
    if(rezhim==0)
    {
    	if(blink<170){ind[0]=-1; ind[1]=-1; ind[2]=-1; ind[3]=-1;}
    	if(blink>170){ind[0]='-'; ind[1]='-'; ind[2]='-'; ind[3]='-';}
    }
    if(rezhim==1)
      {
    	 if(right==1) {tempset=tempset+param1[1];pwm=eeprom_read_byte(&pwm_m[tempset]); if (pwm<255){tempmem=1;tmp=0;}else{tempmem=0;pwm=1;tmp=0;} } 
    	 if(left==1){tempset=tempset-param1[1];pwm=eeprom_read_byte(&pwm_m[tempset]); if (pwm<255){tempmem=1;tmp=0;}else{tempmem=0;pwm=1;tmp=0;} }
      }
    if(rezhim==2)
     {
    	if(butt1==200){if(edit==0){edit=1;tempvar=-1;} else {edit=0; eeprom_write_byte(¶m1eeprom[params], param1[params]);} }
    	if(edit==0)
    	 {
    		  ind[0]='P'; ind[1]=params; ind[2]=-1; ind[3]=-1;
    		  if(right==1){params++;}; if(left==1){params--;}
    			  if(params<0){params=0;}; if(params>3){params=3;}
    	 }
    	if(edit==1)
    	{
    	 if(blink==1 || tempvar!=param1[params])
    		 {
    		 if(param1[params]<100){ind[0]=-1;} else {ind[0]=param1[params]/100;}
    		 if(param1[params]<10) {ind[1]=-1;} else {ind[1]=param1[params]%100/10;}
    		 ind[2]=param1[params]%10;
    	     }
    	     if(blink>170){ind[0]=-1;ind[1]=-1;ind[2]=-1;ind[3]=-1;}
    		tempvar=param1[params];
    		if(right==1){param1[params]++;};if(left==1){param1[params]--;}
    			if(param1[params]<0){param1[params]=0;} if(param1[params]>250){param1[params]=1;}
    		if(params==0) {if(param1[params]<0){param1[params]=0;} if(param1[params]>1){param1[params]=1;}}	
    			if(params==1) {if(param1[params]<1){param1[params]=1;} if(param1[params]>50){param1[params]=50;}}	
    				if(params==2) {if(param1[params]<0){param1[params]=0;} if(param1[params]>250){param1[params]=250;}}	
    					if(params==3) {if(param1[params]<0){param1[params]=0;} if(param1[params]>250){param1[params]=250;}}	
        }
     }
     } //loop
    } //main

    <spoiler />


    Also popular now: