Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
nleahcim
PostPosted: Mar 21, 2009 - 10:59 PM
Raving lunatic


Joined: Feb 19, 2003
Posts: 2233
Location: Seattle, WA

For personal use I bought a Hakko 936 about 7 or 8 years ago. It still works great. I still use the original tip, among others.

At work I have a Weller. Same base unit as this one: http://search.digikey.com/scripts/DkSea ... =WD1001-ND but slightly different iron. It is now about two years old.

Both are fantastic pieces of equipment. The Weller heats up faster and gives me an actual readout of the temperature. It is also much easier to hot-swap tips on the Weller (you have to do it with pliers or something else to protect you from the heat with the Hakko).

Is the Weller worth the extra $300? For personal use, I'd say no. The Hakko is more than adequate for just about anything. I haven't used much Metcal equipment - but I'm sure it's good too. But for personal use - a $100 iron is all you really need.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
steve17
PostPosted: Mar 22, 2009 - 01:47 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2518
Location: New York State

Okay, let's have a contest. My Aoyue 2900 70 watt with digital readout and with the heater in the tips takes 14 seconds to get to 350 C.

My Aoyue 908 35 watt with no digital readout and simple tips without integral heaters takes 27 seconds to get to 300 C.

The digital is much faster to get to 350 C, but I want to solder at 300 C. It defaults to 350 C, so I have to punch buttons to get it down to 300 C. In the end, the analog gets to 300 C almost as fast and I don't have to punch any buttons. I can just sit on my ass and wait.
 
 View user's profile Send private message  
Reply with quote Back to top
gskinner
PostPosted: Mar 22, 2009 - 03:05 AM
Hangaround


Joined: Feb 26, 2004
Posts: 127
Location: broomfield CO 80020

if you watch and wait on ebay you can get a great deal on a metcal iron and tips. but you have to wait.
 
 View user's profile Send private message Visit poster's website 
Reply with quote Back to top
JohnFrost
PostPosted: Mar 23, 2009 - 08:03 PM
Newbie


Joined: Nov 26, 2008
Posts: 3


I've been quite happy with the BlackJack SolderWerks BK3000LFF from Circuit Specialists Inc. This is a digital temperature controlled soldering iron, 70 watts. Heats very rapidly and maintains tip temperature very well, at least for the kind of soldering I do.
Brand new price is $88 and they throw in a free solder fume fan/filter
http://www.circuitspecialists.com
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Apr 25, 2011 - 01:44 AM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

Hi,

I have BlackJack solderwerks BK3000LF station, and it seems it is a copy of AOYUE 2900.

Here's what I have come to, about the electronics:

1. The soldering iron is powered by around 30V rectified but non-filtered voltage.

2. This voltage is switched on/off by a IRF9540 MOSFET, controlled by the AT89C2051 MCU.

3. The MCU switches voltage on/off synchronously, i.e. twice for every period. (100Hz in europe, 120Hz in USA)

4. There is a 1ms dead time on every half-period, and the MCU reads the temperature in this 1ms dead time. The MOSFET is always switched off during dead time, so there isn't any voltage at the output from the station

5. There is a thermocouple in the soldering tip in series with the heater. I suppose the heater connections themselves are used as thermocouple. This gives around 9mV when heated to 350 degrees celsius. One can easily measure this with ordinary multimeter, coupled to the iron power wires. Another soldering iron or a hot air station can be used to heat up the measured solderin iron.

6. During this 1ms dead time, the voltage from the thermocouple is amplified around 300 times by a lm358 opamp , fed to one of the input channels of ADC0832, and read by the MCU.

Maybe I will be able to write a new software for ATTiny somewhere in the future, in order for it to be able to memorize the last temperature that has been set. Switching to 350 degrees every time is pretty disgusting. Smile
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Apr 25, 2011 - 02:32 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2518
Location: New York State

Good work. If you can sell me something that causes it to start off with the previous temperature, I'll go for that. If it just started at 300 degrees, that would work for me.

While you are at it, can you make the automatic off after 30 minutes be really automatic? That's one of the reasons I bought the AOYUE, but it ain't exactly automatic. I have to push three buttons at once at startup to activate it. That takes both hands and my nose. Wink I wish it was automatically automatic, if you know what I mean.

The one problem I've had is the contacts between the tip and the holder. After I had the soldering station for a few weeks, it would beep 5 times and shut down. I think that's because of lousy contacts that prevent it from reading the temperature.

I cleaned the tip and I tried to clean the contacts. I also bent the contacts so they would press harder against the tip. So far, it seems to work.
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Apr 25, 2011 - 02:47 AM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

steve17 wrote:
Good work. If you can sell me something that causes it to start off with the previous temperature, I'll go for that. If it just started at 300 degrees, that would work for me.

While you are at it, can you make the automatic off after 30 minutes be really automatic? That's one of the reasons I bought the AOYUE, but it ain't exactly automatic. I have to push three buttons at once at startup to activate it. That takes both hands and my nose. Wink I wish it was automatically automatic, if you know what I mean.

The one problem I've had is the contacts between the tip and the holder. After I had the soldering station for a few weeks, it would beep 5 times and shut down. I think that's because of lousy contacts that prevent it from reading the temperature.

I cleaned the tip and I tried to clean the contacts. I also bent the contacts so they would press harder against the tip. So far, it seems to work.


Hi,

I got it 3 days ago. I am pretty satisfied with the iron performance so far.

I will let you know if I decide to play around with the software. It looks easy anyway. Smile Only the communication with the ADC is a bit new to me. But I think I will be able to cope with it with some trials and errors.

The way MCU reads the temperature was pretty surprising also. At the first, I thought it reads the heater resistance, but the moment I hooked the oscilloscope to the ADC input cleared nearly all the things out. I was finally pretty sure wat I was dealing with when I hooked the multimeter to the iron's power terminals and heated it up with my hot air station. Smile

Anyway, I will let you know if I decide to play around with the software.

...and axcuse my english, please. Smile
 
 View user's profile Send private message  
Reply with quote Back to top
Jeckson
PostPosted: Apr 25, 2011 - 09:37 AM
Resident


Joined: Feb 15, 2008
Posts: 603
Location: Makassar,Indonesia

No response from urbach?.

With 0.5US$ solder is OK.

Jeckson

נרגעת
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Apr 25, 2011 - 10:04 AM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

Jeckson wrote:
No response from urbach?.

With 0.5US$ solder is OK.

Jeckson

נרגעת


Do you mean someone already made this???

Shocked
 
 View user's profile Send private message  
Reply with quote Back to top
chartman
PostPosted: Apr 25, 2011 - 04:12 PM
Resident


Joined: May 01, 2003
Posts: 577


The company I work for ( 360 + employees, sub contract elec. assy) Uses Metcal exclusively...
 
 View user's profile Send private message  
Reply with quote Back to top
leon_heller
PostPosted: Apr 25, 2011 - 04:21 PM
Raving lunatic


Joined: Jul 27, 2001
Posts: 7429
Location: St. Leonards-on-Sea (UK)

I've used Metcal for years. Old STSS power units can be picked up cheap on Ebay, and can use the newer MX-500 and MX-5000 handpieces and cartridges.

_________________
Leon Heller
G1HSM
 
 View user's profile Send private message Send e-mail Visit poster's website 
Reply with quote Back to top
ka7ehk
PostPosted: Apr 25, 2011 - 05:15 PM
10k+ Postman


Joined: Nov 22, 2002
Posts: 12031
Location: Tangent, OR, USA

Geez, I wish there is a way to "flag" topics so they don't get lost in the nether reaches of the forum!

Jim

_________________
Jim Wagner
Oregon Research Electronics, Consulting Div.
Tangent, OR, USA

"The only thing standing between us and victory is defeat" P.G.Wodhouse in Wooster & Jeeves series
 
 View user's profile Send private message  
Reply with quote Back to top
Jeckson
PostPosted: Apr 26, 2011 - 08:47 AM
Resident


Joined: Feb 15, 2008
Posts: 603
Location: Makassar,Indonesia

Quote:
Jeckson wrote:
No response from urbach?.

With 0.5US$ solder is OK.

Jeckson

נרגעת


Do you mean someone already made this???


It's 0.7US$ now.
Common solder.

Jeckson

נרגעת
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Apr 26, 2011 - 09:22 AM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

Jeckson wrote:
Quote:
Jeckson wrote:
No response from urbach?.

With 0.5US$ solder is OK.

Jeckson

נרגעת


Do you mean someone already made this???


It's 0.7US$ now.
Common solder.

Jeckson

נרגעת


Did you mean someone made a new software for BJ/AOYUE? If so, how to buy?
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: May 02, 2011 - 10:31 PM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

Done so far(AtTiny2313/AVR Studio 5 used):
- It regulates the temperatire a bit faster. I have implemented a PID control of the iron.
- It remembers the last temperature setting on power down.
- The default/reset temperature can be programmed. For example, if you work on 250 degrees, and you have programmed a reset temperature of 320 degrees, it goes to 320 degrees when you push the X button. It remebmers this setting also on powerdown.


ToDo:
- waiting for ATTiny4313, because the 2K Flash on 2313 are completely full. Only 8 bytes left free, despite the long trials to optimise the code for size. I have even used "attribute ((naked))" on the main function, but still, this is not enough.
- The auto sleep function will be implemented with 10,30,60,90 minutes option, and separate option for on/off. This way you will be able to set the minutes, and the station will remember them, and when this feature is turned on, it stays on until you turn it off, no matter if you switch the station on or off.

My first AVR project so far. Smile

Unfortunately, ATTiny2313/4313 reset pin is active low, and the AT89C2052 reset pin is active high. One can program the RSTDIS fuse and use it as a standart I/O pin, but device becomes unprogrmmable in serial mode after this. Because I am using JTAGICE 2 for programming and I don't have a parallel mode programmer, this option uas unacceptable for me. Instead, I had to select internal RC oscillator, cut the PCB trace to the reset pin, and hook it to the PA0/XTAL1 pin. It works like a charm. When the software is completely ready and tested, the reset/PA3 pin can be used as an I/0, external oscillator can be selected, and the RSTDIS fuse can be programmed for a complete compatibility with the AT89C2051 chip, whithout any PCB modifications.
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: May 03, 2011 - 12:55 AM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2518
Location: New York State

You've been busy!
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Mar 22, 2012 - 08:28 PM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

Here is the code (i've used AVRStudio 5):
Code:
#define F_CPU 8000000UL            //CPU Frequency

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sfr_defs.h>
#include <avr/eeprom.h>
#include <util/delay.h>

#define sbi(sfr,bn) (sfr|=_BV(bn))
#define cbi(sfr,bn) (sfr&=~_BV(bn))
#define SetCS sbi(PORTD, PD1)
#define ClrCS cbi(PORTD, PD1)
#define SetCLK sbi(PORTD, PD0)
#define ClrCLK cbi(PORTD, PD0)
#define SetDIDO sbi(PORTB, PB7)
#define ClrDIDO cbi(PORTB, PB7)
#define lbyte(var) ((unsigned char*)&var)[0]
#define ubyte(var) ((unsigned char*)&var)[1]

#define B0Pressed !(PINB&(1<<PB6))   // "+" button
#define B1Pressed !(PINB&(1<<PB5))   // "-" button
#define B2Pressed PINA&(1<<PA0)      // "X" button NOTE: There is two options for the X button.
                           // In the original design, X button is connected to RESET pin of the MCU.
                           // It can be left this way, but the MCU can be programmed only once using serial programming
                           // So, I decided to cut off the signal to reset pin and connect it to PA0 pin.

#define ADC_PERIOD 2            //ADC clock half period in microseconds
#define ADC_AVG 3               //ADC temperature averaging constant, a power of two. Must be between 3 and 8.

#define PID_PGAIN 64            //PID control proportional gain
#define PID_IATTN 3               //PID control integral attenuation, a power of two
#define PID_DATTN 4               //PID control differential gain, a power of two
#define PID_IMIN -64            //PID minimum integral value boundary
#define PID_IMAX 2048            //PID maximum integral value boundary
#define PID_DMIN -256            //PID minimum differential value boundary
#define PID_DMAX 4096            //PID maximum differential value boundary

unsigned char EEPROMPos;         //Current EEPROM saving position
unsigned char ISRTicks;            //ISR Ticks
unsigned char SetTempB;            //ADC set temperature (settemp*3/4)
unsigned int TempAVG;            //Averaged current temperature, as read from ADC
unsigned char CSleepMinutes;
unsigned char CSleepSeconds;
unsigned char CSleepTicks;

struct PType{
   unsigned char Identifier;      //Identifier in EEPROM
   unsigned char RstIndex;         //Current reset temperature index in RstTemp[]
   unsigned char RstTemp[3];      //Reset temperature in degrees/2
   unsigned char SetTemp;         //Current set temperature in degrees/2
   unsigned char SleepMinutes;      //Minutes (10,30,60,90) and on/off flag (128) of sleep function
}Pars;

unsigned char EEPROM_GetChar(unsigned char addr)
{
   do{}while(EECR&(1<<EEPE));      //Wait for completion of previous write.
   EEAR=addr;                  //Set EEPROM address register.
   EECR=(1<<EERE);               //Start EEPROM read operation.
   return EEDR;               //Return the byte read from EEPROM.
}

void EEPROM_PutChar(unsigned char addr, unsigned char new_value)
{
   unsigned char old_value;      //Old EEPROM value.
   unsigned char diff_mask;      //Difference mask, i.e. old value XOR new value.
   unsigned char old_interrupt;   //Stores interrupt flag while programming.

   old_interrupt = SREG & (1<<SREG_I); //Save interrupt flag state.
   cli();
   do{}while(EECR&(1<<EEPE));      //Wait for completion of previous write.
   EEAR=addr;                  //Set EEPROM address register.
   EECR=(1<<EERE);               //Start EEPROM read operation.
   old_value=EEDR;               //Get old EEPROM value.
   diff_mask=old_value ^ new_value; //Get bit differences.
      
   if(diff_mask&new_value){      //Check if any bits are changed to '1' in the new value.      
      if(new_value!=0xff){      //Check if any bits in the new value are '0'.         
         EEDR=new_value;         //Set EEPROM data register.
         EECR=(1<<EEMPE)|(0<<EEPM1)|(0<<EEPM0); //Set Master Write Enable bitand Erase+Write mode.
         EECR|=(1<<EEPE);      //Start Erase+Write operation.
      }
      else{                  //Now we know that all bits should be erased.
         EECR=(1<<EEMPE)|(1<<EEPM0); //Set Master Write Enable bit and Erase-only mode.
         EECR|=(1<<EEPE);      //Start Erase-only operation.
      }
   }
   else{                     //Now we know that _no_ bits need to be erased to '1'.      
      if(diff_mask){            //Check if any bits are changed from '1' in the old value.
         EEDR=new_value;         //Set EEPROM data register.
         EECR=(1<<EEMPE)|(1<<EEPM1); //Set Master Write Enable bit and Write-only mode.
         EECR|=(1<<EEPE);      //Start Write-only operation.
      }
   }
   SREG|=old_interrupt;         //Restore interrupt flag state.
}

void LoadPars(unsigned char addr)
{
   unsigned char i;
   for(i=0;i<sizeof(Pars);i++){
      ((unsigned char*)&Pars)[i]=EEPROM_GetChar(addr+i);
   }         
}

void SavePars(unsigned char addr)
{
   unsigned char i;
   for(i=0;i<sizeof(Pars);i++){
      EEPROM_PutChar(addr+i,((unsigned char*)&Pars)[i]);
   }         
}

ISR(TIMER0_OVF_vect)            //Used to detect power off
{
   if(!(PIND&(1<<PIND2))){
      PORTD|=0b00111000;
      SavePars(EEPROMPos);      
      _delay_ms(2000);
      __asm__ __volatile__ ("rjmp __vectors");
   }   
}

ISR(INT0_vect)                  //Main interrupt routine on every mains voltage half period
{
   unsigned char i,rb;
   int PWMP,PWMPRCL,PWMIL,PWMDL;
   static int PWMCNT;
   static int PWMPOLD;
   static int PWMI;
   static int PWMD;
   static int PWMPRC;

   TCCR0B=0;                  //Stop monitoring of the mains voltage
   sbi(PORTD,PD6);               //Stop the power to the iron
   ISRTicks++;
   if(ISRTicks&1){               //Run once on every full mains voltage period
      _delay_us(600);            //Wait for thermocouple voltage

      sbi(DDRB,PB7);            //switch to Output on DIDO
      SetDIDO;               //START bit = 1
      ClrCLK;
      ClrCS;   
      _delay_us(ADC_PERIOD);      //tset-up
      SetCLK;         
      _delay_us(ADC_PERIOD);
      ClrCLK;
   
      SetDIDO;               //SGL/DIF = 1
      _delay_us(ADC_PERIOD);         
      SetCLK;         
      _delay_us(ADC_PERIOD);
      ClrCLK;
   
      SetDIDO;               //ODD/SIGN = 1      
      _delay_us(ADC_PERIOD);   
      SetCLK;         
      _delay_us(ADC_PERIOD);
      ClrCLK;
   
      cbi(DDRB,PB7);            //switch to Input on DIDO
      SetDIDO;               //Activate Pull-Up
      _delay_us(ADC_PERIOD);
      SetCLK;
      _delay_us(ADC_PERIOD);
      ClrCLK;
      _delay_us(ADC_PERIOD);
         
      for(i=8;i;i--)            //Read thermocouple voltage from ADC
      {
         SetCLK;
         rb<<=1;
         if(PINB&(1<<PB7))rb++;
         _delay_us(ADC_PERIOD);
         ClrCLK;
         _delay_us(ADC_PERIOD);
      }
      SetCS;
      
      TempAVG=TempAVG-(TempAVG>>ADC_AVG)+rb;   //Average last 8 thermocouple voltages
            
      PWMP=(SetTempB-(TempAVG>>ADC_AVG));      //PID proportional value calculation
      
      PWMIL=PWMI+PWMP;                  //PID integral value calculation
      if(PWMIL>PID_IMAX)PWMIL=PID_IMAX;
      if(PWMIL<PID_IMIN)PWMIL=PID_IMIN;
      PWMI=PWMIL;

      PWMDL=PWMD+PWMP-PWMPOLD;            //PID differential value calculation
      if(PWMDL>PID_DMAX)PWMDL=PID_DMAX;
      if(PWMDL<PID_DMIN)PWMDL=PID_DMIN;
      PWMD=PWMDL;

      PWMPOLD=PWMP;                     //Save last proportional value
      
      PWMPRCL=((PWMP*PID_PGAIN)+(PWMIL>>PID_IATTN)+(PWMDL>>PID_DATTN))>>2;   //Calculation of PWM percentage
      if(PWMPRCL<0)PWMPRCL=0;
      if(PWMPRCL>256)PWMPRCL=256;      
      PWMPRC=PWMPRCL;
   }
   PWMCNT+=PWMPRC;                        //Do the PWM
   if(ubyte(PWMCNT)){
      if(CSleepTicks|CSleepSeconds|CSleepMinutes)cbi(PORTD,PD6);
      ubyte(PWMCNT)=0;
   }   
   //Start monitoring of mains voltage.
   GTCCR=1;         //Reset timer prescaler         
   TCNT0=224;         //Timer0 overflow in 4mS
   TCCR0B=0b00000101;   //Timer0 clock = clkio/1024
   
   if(Pars.SleepMinutes&128){
      if(CSleepTicks){
         CSleepTicks--;
      }
      else{
         if(CSleepSeconds|CSleepMinutes){
            CSleepTicks=99;
            if(CSleepSeconds){
               CSleepSeconds--;
            }
            else{
               if(CSleepMinutes){
                  CSleepMinutes--;
                  CSleepSeconds=59;
               }
            }                  
         }
      }      
   }
}

void main() __attribute__ ((noreturn));
void main(){
unsigned char i,i1;
unsigned int di;
unsigned char CDig;
unsigned char LISRTicks;
unsigned char DisplayTicks;
unsigned char ModeTicks;      
unsigned char Mode,OldMode;
unsigned char BeepTicks;
unsigned char DoBeep;
unsigned char BlinkTicks, BlinkPeriod;
unsigned char ButtonTicks[3];
unsigned char LastButtonTicks[3];
unsigned char AlarmTicks;
   cli();
   DDRB=0b00011111;
   DDRD=0b01111011;
   PORTA=0xFF;
   PORTB=0xFF;
   PORTD=0xFF;
   MCUCR=(MCUCR&0b11110000)|0b00000010;   
   GIMSK=0b01000000;
   TIMSK=0b00000010; //timer 0 overflow enable
   
   Pars.Identifier=0xFE;
   Pars.RstTemp[0]=150;
   Pars.SetTemp=150;
   Pars.SleepMinutes=30;
   
   for(i=0;i<=(255-sizeof(Pars));i+=sizeof(Pars)){   //search and read saved values in EEPROM
      i1=EEPROM_GetChar(i);
      switch(i1){
         case 0xFF:
            break;
         case 0xFE:
            EEPROMPos=i+sizeof(Pars);   
            if(EEPROMPos>255-sizeof(Pars))EEPROMPos=0;
            LoadPars(i);
            if(Pars.RstIndex>2)Pars.RstIndex=0;
            for(i1=0;i1<=2;i1++){
               if(((Pars.RstTemp[i1]<75)&&(Pars.RstTemp[i1]!=0))||(Pars.RstTemp[i1]>225))Pars.RstTemp[i1]=150;
            }
            for(i1=0;(i1<=2)&&(Pars.RstTemp[Pars.RstIndex]!=0);i1++){
               if(Pars.RstIndex<2){
                  Pars.RstIndex++;
               }
               else{
                  Pars.RstIndex=0;
               }               
            }
            if((Pars.SetTemp<75)||(Pars.SetTemp>225)){
               if(Pars.RstTemp[Pars.RstIndex]){
                  Pars.SetTemp=Pars.RstTemp[Pars.RstIndex];
               }
               else{
                  Pars.SetTemp=150;
               }
            }            
            switch(Pars.SleepMinutes&127){
               case 10:
               case 30:
               case 60:
               case 90:
                  break;
               default:
                  Pars.SleepMinutes=30;
            }            
         default:
            for(i1=0;i1<sizeof(Pars);i1++)EEPROM_PutChar(i+i1,0xFF);         
      }
   }

   SavePars(EEPROMPos);

   SetTempB=(Pars.SetTemp*3)/4;
   
   CSleepMinutes=Pars.SleepMinutes&127;
                  
   for(i=0;i<=2;i++){
      ButtonTicks[i]=0;
      LastButtonTicks[i]=0;
   }   
   if(Pars.SleepMinutes&128){
      Mode=5;
      BlinkPeriod=20;
   }
   else{
      Mode=1;
      BlinkPeriod=0;
   }
   ModeTicks=100;   
   DisplayTicks=0;
   BlinkTicks=0;
   DoBeep=1;
   BeepTicks=2;
   AlarmTicks=0;
   
   sei();
         
   for(;;){
      if(LISRTicks!=ISRTicks){      
         LISRTicks=ISRTicks;
         if(DisplayTicks)DisplayTicks--;
         if(ModeTicks)ModeTicks--;
         if(!ModeTicks){
            Mode=0;
            BlinkPeriod=0;
         }
         if((BlinkTicks++)>BlinkPeriod)BlinkTicks=0;
         if(BeepTicks){
            BeepTicks--;
            cbi(PORTB,PB4);
         }
         else sbi(PORTB,PB4);
            
         i=TempAVG>>ADC_AVG;
         if(i>185){
            if(AlarmTicks<255)AlarmTicks++;
         }
         else{
            AlarmTicks=0;
         }                  
         if(B0Pressed){
            if(ButtonTicks[0]++>240)ButtonTicks[0]--;
         }else ButtonTicks[0]=0;
         if(B1Pressed){
            if(ButtonTicks[1]++>240)ButtonTicks[1]--;
         }else ButtonTicks[1]=0;
         if(B2Pressed){
            if(ButtonTicks[2]++>240)ButtonTicks[2]--;
         }else ButtonTicks[2]=0;
         if(B0Pressed|B1Pressed|B2Pressed){            
            CSleepMinutes=Pars.SleepMinutes&127;
            CSleepSeconds=0;
            CSleepTicks=0;
         }         
      }      
      
      for(i=0;i<=2;i++){
         i1=0;
         if(ButtonTicks[i]){
            if(LastButtonTicks[i]){
               if((ButtonTicks[i]>50)&&(i!=2)){
                  ButtonTicks[i]=48;
                  i1=0x10+i;
               }               
            }
            else{
               i1=0x10+i;
            }            
         }
         else{
            if(LastButtonTicks[i])i1=0x20+i;
         }
         LastButtonTicks[i]=ButtonTicks[i];
         
         while(i1){
            switch(i1){
               case 0x10: //button "+" down
                  switch(Mode){
                     case 2:
                        Mode=5;
                        Pars.SleepMinutes|=128;
                        i1=0x82;
                        break;
                     case 4:
                        if(Pars.RstTemp[Pars.RstIndex]<225)Pars.RstTemp[Pars.RstIndex]++;
                        if(Pars.RstTemp[Pars.RstIndex]<75)Pars.RstTemp[Pars.RstIndex]=75;
                        i1=0x83;
                        break;
                     case 5:
                        if(Pars.SleepMinutes&128){
                           switch(Pars.SleepMinutes&127){
                              case 10:
                                 Pars.SleepMinutes=30+128;
                                 break;
                              case 30:
                              case 60:
                                 Pars.SleepMinutes+=30;
                                 break;
                              default:
                                 Pars.SleepMinutes=10+128;
                           }                           
                        }
                        else{
                           Pars.SleepMinutes|=128;                                                      
                        }
                        i1=0x82;
                        break;
                     case 6:
                        BlinkPeriod=0;
                        i1=0x80;
                        break;
                     default:
                        if(Pars.SetTemp<225)Pars.SetTemp++;         
                        i1=0x80;
                  }         
                  break;
               case 0x11: //button "-" down   
                  switch(Mode){
                     case 2:
                        Mode=5;
                     case 5:
                        Pars.SleepMinutes&=127;
                        i1=0x82;
                        break;
                     case 4:
                        if(Pars.RstTemp[Pars.RstIndex]>=75)Pars.RstTemp[Pars.RstIndex]--;
                        if(Pars.RstTemp[Pars.RstIndex]<75)Pars.RstTemp[Pars.RstIndex]=0;
                        i1=0x83;
                        break;
                     case 6:
                        BlinkPeriod=0;
                        i1=0x80;
                        break;
                     default:
                        if(Pars.SetTemp>75)Pars.SetTemp--;
                        i1=0x80;                        
                  }         
                  break;
               case 0x12: //button "X" down
                  switch(Mode){
                     case 3:
                        i1=0x82;
                        break;
                     case 4:
                        if(++Pars.RstIndex>2)Pars.RstIndex=0;
                        i1=0x83;
                        break;
                     case 6:
                        i1=0;
                        break;
                     default:
                        Mode=2;
                        i1=0x83;
                        break;                     
                  }
                  break;

               case 0x22: //button "X" up
                  switch(Mode){
                     case 2:
                        for(i1=0;i1<=2;i1++){
                           if((Pars.RstTemp[Pars.RstIndex]<75)||(Pars.RstTemp[Pars.RstIndex]>225)){
                              if(++Pars.RstIndex>2)Pars.RstIndex=0;
                           }                           
                        }                                                   
                        if((Pars.RstTemp[Pars.RstIndex]>=75)&&(Pars.RstTemp[Pars.RstIndex]<=225)){
                           Pars.SetTemp=Pars.RstTemp[Pars.RstIndex];
                        }
                        Mode=3;
                        i1=0x81;
                        break;
                     case 3:
                        if(++Pars.RstIndex>2)Pars.RstIndex=0;
                        for(i1=0;i1<=1;i1++){
                           if((Pars.RstTemp[Pars.RstIndex]<75)||(Pars.RstTemp[Pars.RstIndex]>225)){
                              if(++Pars.RstIndex>2)Pars.RstIndex=0;
                           }                           
                        }                                                   
                        if((Pars.RstTemp[Pars.RstIndex]>=75)&&(Pars.RstTemp[Pars.RstIndex]<=225)){
                           Pars.SetTemp=Pars.RstTemp[Pars.RstIndex];
                        }
                        i1=0x81;
                        break;
                     case 6:      
                        BlinkPeriod=0;                  
                        i1=0x80;
                        break;
                     default:
                        i1=0;
                  }                  
                  break;
               case 0x80: //Exit 1
                  Mode=1;
               case 0x81: //exit 2
                  SetTempB=(Pars.SetTemp*3)/4;
                  DoBeep++;
               case 0x82:
                  ModeTicks=100;
                  i1=0;
                  break;
               case 0x83: //Exit 4
                  ModeTicks=255;      
                  i1=0;
                  break;                                 
               default:
                  i1=0;
            }
            DisplayTicks=0;   //Display immediately
         }
      }      
      if(AlarmTicks>=200){
         Mode=7;
         ModeTicks=100;
         DisplayTicks=0;         
      }
      else{
         if(Mode==7){
            Mode=0;
            DisplayTicks=0;
            BeepTicks=0;
         }
      }
      
      if((!DisplayTicks)||(OldMode!=Mode)){
         DisplayTicks=10;
         OldMode=Mode;
         i1=Mode+0x10;
         while(i1){
            switch(i1){
               case 0x10:   //Mode 0 - show real temperature
                  if((!CSleepMinutes)&&(CSleepSeconds<=10)){
                     BeepTicks=20;
                     Mode=6;
                     i1=0x16;
                  }
                  else
                  {
                     i=TempAVG>>ADC_AVG;
                     if((i<(SetTempB-1))||(i>(SetTempB+1))){
                        di=TempAVG/(3<<(ADC_AVG-3));                  
                        i1=0xFF;
                     }
                     else{                     
                        if(DoBeep){
                           DoBeep=0;
                           BeepTicks=2;
                        }
                        di=Pars.SetTemp<<1;
                        i1=0xFF;
                     }
                  }
                  break;
               case 0x11:   //Mode 1 - Show set temperature after +/- is pressed
                  di=Pars.SetTemp<<1;
                  i1=0xFF;                  
                  break;
               case 0x12:   //Mode 2 - waiting for 2 seconds to enter mode 4
                  if(ButtonTicks[2]>=200){
                     BeepTicks=5;
                     Mode=4;
                     i1=0x14;
                     ModeTicks=200;
                     DisplayTicks=0;
                  }
                  else{
                     i1=0x10;
                  }
                  break;
               case 0x13: //Mode 3 - The temperature was set to one of the reset values
                  di=Pars.SetTemp<<1;
                  i1=0xFF;
                  break;
               case 0x14:  //Mode 4 - Show current reset temperature
                  BlinkPeriod=20;
                  di=Pars.RstTemp[Pars.RstIndex]<<1;
                  i1=0xFF;
                  break;
               case 0x15:  //Mode 5 - Show sleep status (on/off,minutes)
                  if(Pars.SleepMinutes&128){
                     di=0x0E00+(((Pars.SleepMinutes&127)/10)<<4);
                  }
                  else{
                     di=0x0ECC;
                  }
                  i1=0;
                  break;   
               case 0x16:   //Mode 6 - show sleep seconds before sleep
                  if((!CSleepMinutes)&&(CSleepSeconds<=10))ModeTicks=100;
                  if(CSleepSeconds|CSleepTicks){                     
                     di=0xE00+((CSleepSeconds/10)<<4)+(CSleepSeconds%10);
                     BlinkPeriod=0;
                  }
                  else{
                     di=0xE00;
                     BlinkPeriod=200;   
                  }
                  i1=0;
                  break;               
               case 0x17: //Mode 7 - Soldering iron problem alarm
                  BeepTicks=100;
                  di=0xCCC;
                  i1=0;
                  break;
               case 0xFF:  //Encode the BINARY in di to BCD
                  di<<=1;
                  for(i=0;i<2;i++){
                     di<<=1;
                     if((di&0xF00)>=0x500)di+=0x300;
                  }         
                  di>>=3;
                  for(i=0;i<4;i++){
                     if((di&0xF0)>=0x50)di+=0x30;
                     if((di&0xF00)>=0x500)di+=0x300;
                     di<<=1;
                  }
                  di>>=4;
                  i1=0;
                  break;
               default:
                  i1=0;
            }            
         }
      }
      PORTD|=0b00111000;
      if(BlinkTicks>=BlinkPeriod>>2){
         if(!(CDig=(CDig<<1)&0b00111000))CDig=8;
         switch(CDig){
            case 8:
               PORTB=(PORTB&0xF0)|(di&0x000F);
               break;
            case 16:
               PORTB=(PORTB&0xF0)|((di>>4)&0x000F);
               break;
            case 32:
               PORTB=(PORTB&0xF0)|((di>>8)&0x000F);
               break;
         }      
         PORTD&=~CDig;
         _delay_us(1000);
      }      
   }
}
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Mar 22, 2012 - 08:53 PM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

You need ATTiny4313 device to be able to use the above code. ATTiny2313 does not have enough program memory for it. Also, I am using the internal RC oscillator on ATTiny, so the original one can be removed from the PCB. And, of course, you shoult make the needed adjustment in fuse settings for it to work this way.

And the new functions:

"X"+"-" disables the sleep timer.
"X"+"+" sets the sleep timer period in minutes (10,30,60,90)
The sleep function is remembered, so it will be in the same state after turning off and on again.

Also 3 preset temperatures can be remembered.
It is done by pressing "X" button and holding it until the display begins to flash.
Then release the "X" button and, pressing the "+" and "-" buttons you can set the temperature to remember. After the temperature is set, you can switch to next preset temperature setting by shortly pressing and releasing the "X" button. After the second preset temperature is set, you can program the third preset temperature the same way.
When you have set all you want, after 2 seconds the display will switch to real temperature display mode.
When you want to select one of the preset temperatures, this is done by shortly pressing and releasing the "X" button several times until the proposed temperature setting is shown on the display.

Of course, the last temeprature (no matter if you have selected one of the preset temperatures, or you have used "+" and "-" to select any other temperature) is also remembered after turning the solder station off.

If you want to reset the device setting to defaults, this is done by holding the "X" button while turning on the solder station.

...and please, excuse my english.

From my experiance so far, my preset temperatures are 250, 300, and 350 degrees celcius. This way, with a click or two on the "X" button I can easily select the temperature I need, and after this I can correct the temperature with the "+" and "-" buttons.

The code is far from perfection, but it works and I don't see any reason for refining it. The temperature control method is done by PID algothitm, and is a little faster than original. On my machine it is easily seen how it works looking at the dot on the display. You will notice it works a little different from the original one, contolling the soldering iron power in much shorter periods (in fact, the shorter possible period is the period of the mains supply).

Be informed that my Mains supply is 50Hz, and yours mqy be 60Hz. So, when you turn on the solder station for the first time, take extra care if it works as it should, and turn it of immediately if the soldering iron tends to overheat, which will destroy it. I have destroyed 3 while writing this software, so it was not a cheap process for me. Smile

I can send you the entire AVRStudio 5 project, but I don't know how to attach it here.


Last edited by sparkybg on Mar 22, 2012 - 08:56 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
sparkybg
PostPosted: Mar 22, 2012 - 09:03 PM
Newbie


Joined: Apr 25, 2011
Posts: 12
Location: Sofia, Bulgaria

The tips with integrated heater on my soldering iron are priced $5 - $20.

Make a search in google for HAKKO T12 ot T15 tips. My solder station is "BlackJack BK3000LF" (you can do a search for this in google also), but as far as I can see, AOYUE units are using the same controllers, with slightly different front panel PCB, but the schematics looks identical, as far as I can see looking at the PCB photos.

I am extremely pleased with performance of my unit. I can use it both for soldering TQFP64 with 0.5mm step with the smallest tip, and soldering a TO-247 with a bigger tip. After all, this is a 70W soldering statio, despite the tiny tips available.
 
 View user's profile Send private message  
Reply with quote Back to top
steve17
PostPosted: Mar 23, 2012 - 02:57 PM
Raving lunatic


Joined: Sep 07, 2004
Posts: 2518
Location: New York State

sparkybg wrote:
I can send you the entire AVRStudio 5 project, but I don't know how to attach it here.
If you haven't seen the attachment mechanism, you can get it two ways.

If you type anything in the Quick Reply window, and click Preview, you will see it. Another way to get it is to click New Reply at the top of the page.

Then click Browse under "Add an Attachment".
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits