搜索
bottom↓
回复: 56

Yet another Hakko Clone ("YAHC")

[复制链接]

出0入0汤圆

发表于 2013-4-8 04:05:16 | 显示全部楼层 |阅读模式
Long story short, I decided to make a solder station controller to drive Hakko 907 (or similar) handles.

There are ton of analog solutions but I decided to use a mcu - and in this case a PIC16F684.

Basic principles as follows: the controller reads the ptc to detect sensor and then turn on / off the heater to achieve desired temperature.

Basic design elements:

1) a minimalist approach: as simple as possible - a pot to set the desired temperature and the mcu performs the ptc.
2) heater control: via a power mosfet. No PID. The heater is turned on if the target temperature exceeds the current temperature. Otherwise, it is turned off.
3) power source: a laptop power supply. In my case, I used a  19.6v 4.6a HP laptop supply.
4) optional lcd display: a 1602 lcd lcd can be optionally connected to display target temperature and iron temperature. the lcd can be used for debugging.
5) optional LED indicator: I used a RGB led to indicate controller status.
6) optional Celsius / Fahrenheit conversion: user selectable C/F conversion, via a jumper.

It should be able to drive any 907 handle with a 5-pin ****FEMALE**** connector: as I don't have a mountable female 5-pin connector. For the standard Hakko male connector, you will need a male-to-female connector.

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

 楼主| 发表于 2013-4-8 04:23:23 | 显示全部楼层
Here is the basic schematic:



Note:

1) PORTC drives the lcd, in 4-bit mode;
2) PORTA reads the sensors / pot and then control the mosfet.
  RA0 controls the mosfet switch. I should have used a logic level mosfet for Q1 but I don't have one handly so I used a FDP3672 - a standard 36amp mosfet. I ran ice cold so I am using it;
  RA1 drive one of the two leds via a resistor (not shown);
  RA2 reads desired temperature settings (set by user via RV1). R1/C1 optional;
  RA3 reads the celsius / fahrenheit setting - optional.
  RA4 reads the ptc (Rt) in the iron handle via Rm - Rm to be specified in the code. R2/C2 optional.
  RA5 drives the other led via a resistor (not shown)

  C6 bypasses the mcu - optional but strongly recommended;

  C3 optiona;

  R3 for simulation only. Do NOT use in real circuit.

  MCU runs under 4Mhz internal rc oscillator.

  Q1 drives the HEATER (from 3ohm cold to about 5ohm hot).

So if you really want to the minimalist route, the whole design can be reduced down to the  mcu + a resistor (Rm), a pot (RV1), a mosfet (Q1) and a voltage regulator for the mcu (a resistor + led for example).

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-4-8 05:16:52 | 显示全部楼层
If there is no PID,how can you set the temperature accurately and quickly?

出110入0汤圆

发表于 2013-4-8 08:05:06 | 显示全部楼层
简单的分段比例应该也能控制得大概,很多焊台都是不带mcu的

出0入0汤圆

 楼主| 发表于 2013-4-9 08:26:03 | 显示全部楼层
本帖最后由 millwood0 于 2013-4-9 08:27 编辑

I made a small test to see if the target temperature setting is done correctly - it is.

Here is the code: not tested with a heater yet.

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //version history
  4. //4/07/2013: v0.90 - initial code integrated
  5. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  6. //4/08/2013: v0.99 - hot-tested display + target temperature setting.

  7. #include <htc.h>
  8. #include <string.h>                                        //we use strcpy
  9. #include "config.h"                                        //internal rc oscillator, no clock out
  10. #include "gpio.h"
  11. #include "delay.h"
  12. #include "adc.h"
  13. #include "lcd_4bit.h"                                //we use lcd4bit
  14. #include "misc.h"                                        //we use ultoa

  15. //hardware configuration
  16. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  17. #define HEATER_DDR                TRISA
  18. #define HEATER                        (1<<1)                //heater Positive - active high

  19. #define SENSOR_PORT                PORTA                //temperature sensor
  20. #define SENSOR_DDR                TRISA
  21. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  22. #define SENSOR_ADC                ADC_AN3                //pa.4 = an3
  23. #define Vref                        5000ul                //reference voltage for the adc
  24. #define Rm                                1100                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  25. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  26. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  27. #define Temp_Low                25                        //low temp
  28. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  29. #define Temp_High                400                        //high temp
  30. #define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  31. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  32. #define Ohm2Temp(dohm)        (Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low))

  33. #define TARGET_PORT                PORTA                //pot to set target temperature
  34. #define TARGET_DDR                TRISA
  35. #define TARGET                        (1<<2)                //target temperature set on pa2
  36. #define TARGET_ADC                ADC_AN2                //pa.2=an2
  37. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  38. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  39. //specify led indicators
  40. //we use two leds
  41. //green led - on = target temperature has been reached
  42. //red led - on = heater on (target temperature has not been reached)
  43. #define LED_PORT                PORTA                //port for green led indicators
  44. #define LED_DDR                        TRISA
  45. #define LEDG                        (1<<5)                //green led indicator. comment out if not used
  46. #define LEDR                        (1<<0)                //red led indicator. comment out if not used

  47. #define LOOP_PR                        100                        //loop period, in ms

  48. #define LCD_DEGREEC                1                        //lcd_degree char

  49. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  50. //end hardware configuration

  51. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  52. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  53. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  54. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  55. //celsius / fahrenheit selector
  56. #define C2F_PORT                PORTA
  57. #define C2F_DDR                        TRISA
  58. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  59. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  60. //global variables
  61. unsigned char loop_cnt=0;                        //loop counter
  62. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  63. unsigned short tgt_adc, tgt=0;
  64. unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  65. //for the lcd - lcd16x2
  66. unsigned char vRAM[17];                                //display ram
  67. const unsigned char str0[]="938 Ctrller v0.9";
  68. const unsigned char ver[] ="--version  0.9--";
  69. const unsigned char str1[]="TARGET=    C    ";
  70. const unsigned char str2[]="SENSOR=    C    ";
  71. const unsigned char str3[]="TGT=    /TMP=   ";

  72. const unsigned char lcd_degreeC[]={
  73.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  74. const unsigned char lcd_up[]={
  75.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  76.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  77.         };

  78. #define LCD_UP                        2                                                        //0x01 is special charter
  79.        
  80. //initialize the controller
  81. void ctrl_init(void) {
  82.         HEATER_OFF(HEATER);                                        //turn off heater
  83.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  84.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  85.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  86.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  87.         IO_IN(TARGET_DDR, TARGET);                //target as input
  88.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  89.         adc_init();                                                //reset the adc module
  90.        
  91.         //load up lcd special chacterators
  92.         lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  93.         lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  94. }

  95. //read solder sensors
  96. unsigned short read_sensor(void) {
  97.         //unsigned short tmp;                                //tmp variable
  98.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  99.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  100.         //return ADC2Ohm(tmp);
  101. }


  102. //read the pot that sets the target temperature
  103. //adc 0 -> TARGET_MIN
  104. //adc 1023 -> TARGET_MAX
  105. unsigned short read_target(void) {
  106.         //unsigned short tmp;                                //tmp variable
  107.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  108.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  109. }

  110. //reset the chip
  111. void mcu_init(void) {
  112.         IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  113.        
  114.         ANSEL=0x00;                                                //all pins PORTA
  115.        
  116.         //ANSELH=0x00;

  117.         CMCON0 = 0x07;                                        //turn off analog comparators
  118.         //CM2CON0 = 0x00;

  119. }

  120. //adc the sensors
  121. void ctrl_adc(void) {
  122.         lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  123.         if (lcd_displayC) {        //pin is pulled high -> celsius
  124.                 tmp=read_sensor();                        //read the pot / target temperature
  125.                 tgt=read_target();                        //read temperature sensor,
  126.         } else {                                                //pin is pulled low - fahrenheit
  127.                 tmp=C2F(read_sensor());                        //read the pot / target temperature
  128.                 tgt=C2F(read_target());                        //read temperature sensor,
  129.         }
  130. }

  131. //control the heater
  132. void ctrl_heater(void) {
  133.         //temperature control logic
  134.         if (tmp < tgt) {
  135.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  136.                 HEATER_ON(HEATER);                        //turn on the heater
  137.         } else {
  138.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  139.                 HEATER_OFF(HEATER);                        //turn off the heater
  140.         }

  141. }

  142. //display - 1line format
  143. void ctrl_display1(void) {
  144.         //process line0
  145.         strcpy(vRAM, str3);
  146.         ultoa(&vRAM[4], tgt, 3);
  147.         ultoa(&vRAM[13], tmp, 3);
  148.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  149.         lcd_display(LCD_Line0, vRAM);
  150. }

  151. //display - 2line format
  152. void ctrl_display2(void) {
  153.         //process line0
  154.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  155.         if(lcd_displayC == 0) vRAM[11]='F';
  156.         ultoa(&vRAM[7], tgt, 3);
  157.         ultoa(&vRAM[12], tgt_adc, 4);
  158.         if (tgt > tmp) vRAM[6]=LCD_UP;
  159.         lcd_display(LCD_Line0, vRAM);
  160.                
  161.         //process line1
  162.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  163.         if (lcd_displayC == 0) vRAM[11]='F';
  164.         ultoa(&vRAM[7], tmp, 3);
  165.         ultoa(&vRAM[12], tmp_adc, 4);
  166.         lcd_display(LCD_Line1, vRAM);
  167.        
  168. }

  169. void main(void)
  170. {
  171.         mcu_init();                                                //reset the chip
  172.         lcd_init();                                                //reset the lcd
  173.         ctrl_init();                                        //reset the controller

  174.         //display sign-on message
  175.         strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  176.         strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  177.         delay_ms(1000);

  178.         while (1){
  179.                 //TODO Auto-generated main function

  180.                 //read the tempeature info
  181.                 //HEATER_OFF();                                //turn off the heater
  182.                 //read the sensors
  183.                 ctrl_adc();
  184.                
  185.                 //control the heater
  186.                 ctrl_heater();
  187.                
  188.                 //update display
  189.                 //ctrl_display1();                        //one-line display
  190.                 ctrl_display2();                        //two-line display
  191.                
  192.                 //waste some time
  193.                 delay_ms(LOOP_PR);                //waste some time
  194.         }
  195. }
复制代码
Fully compiled (picc9.65 I think), it takes about half of the rom in 16F684.

出0入0汤圆

 楼主| 发表于 2013-4-9 08:27:06 | 显示全部楼层
Notice that heater is now on PA1, not PA0 - It made wiring on my board slightly easier.

出0入0汤圆

 楼主| 发表于 2013-4-9 08:30:11 | 显示全部楼层
If there is no PID,how can you set the temperature accurately and quickly?


The temperature is set via a pot so it can be done as fast as your fingers turn.

As for maintaining the target temperature, I am running each loop every 100ms so every 1/10th of a second, the controller is reading the temperature and turning on / off the heater - given the thermal constant (being far longer than 100ms), that's more than enough.

Once I have the heater wired in, I will see how much error I am dealing with.

出0入0汤圆

 楼主| 发表于 2013-4-9 08:31:46 | 显示全部楼层
Here is the hex file, in case you want to run your own.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-4-9 08:39:53 | 显示全部楼层
米兄的帖子一定要顶的。顺便记号收藏。

出0入0汤圆

 楼主| 发表于 2013-4-9 09:23:33 | 显示全部楼层
Thanks.

I think you can implement the same thing (without lcd support) on a 12F675 (8pdip), or lcd via a shift register (74hc164).

出0入0汤圆

 楼主| 发表于 2013-4-9 21:12:39 | 显示全部楼层
I ran the heater under 12Vdc and set the target temperature to 300c. It fluctuates from 297 - 304c every once in a while but mostly in 299 and 302c.

出0入0汤圆

 楼主| 发表于 2013-4-10 05:43:40 | 显示全部楼层
Additional test:

1) at 400c, the temperature fluctuates from 398 - 401c. Not bad.
2) from room temperature, it takes about 30 seconds to get to 300c.

All under 12v.

出0入0汤圆

 楼主| 发表于 2013-4-10 05:46:13 | 显示全部楼层
Bad news:

here is a huge bug hiding in this line:
  1.          return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
复制代码
Let me know if you could spot why.



出0入0汤圆

 楼主| 发表于 2013-4-10 07:00:38 | 显示全部楼层
Under 19.6Vdc, it reaches 300c in 6 seconds and 400c in another 6 seconds.

Temperature fluctuates about +/-4 degrees around the target temperature.

出0入0汤圆

 楼主| 发表于 2013-4-10 07:02:08 | 显示全部楼层
The power supply I use (20v 4.6amp for HP 8440p) drops from 19.6v no load to 18.7v @ 1amp and 17.8v@4amp.

The mosfet runs cold, with a small heatsink.

出0入0汤圆

 楼主| 发表于 2013-4-10 07:34:58 | 显示全部楼层
Here is the complete schematic:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-10 07:35:21 | 显示全部楼层
Code:

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //version history
  4. //4/07/2013: v0.90 - initial code integrated
  5. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  6. //4/08/2013: v0.99 - hot-tested display + target temperature setting.
  7. //4/09/2013: v1.00 - fixed sensor temperature overflow issue. First operational release.

  8. #include <htc.h>
  9. #include <string.h>                                        //we use strcpy
  10. #include "config.h"                                        //internal rc oscillator, no clock out
  11. #include "gpio.h"
  12. #include "delay.h"
  13. #include "adc.h"
  14. #include "lcd_4bit.h"                                //we use lcd4bit
  15. #include "misc.h"                                        //we use ultoa

  16. //hardware configuration
  17. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  18. #define HEATER_DDR                TRISA
  19. #define HEATER                        (1<<1)                //heater Positive - active high

  20. #define SENSOR_PORT                PORTA                //temperature sensor
  21. #define SENSOR_DDR                TRISA
  22. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  23. #define SENSOR_ADC                ADC_AN3                //pa.4 = an3
  24. #define Vref                        5000ul                //reference voltage for the adc
  25. #define Rm                                1200                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  26. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  27. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  28. #define Temp_Low                25                        //low temp
  29. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  30. #define Temp_High                400                        //high temp
  31. #define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  32. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  33. #define Ohm2Temp(dohm)        (((dohm)<dOhm_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low)))

  34. #define TARGET_PORT                PORTA                //pot to set target temperature
  35. #define TARGET_DDR                TRISA
  36. #define TARGET                        (1<<2)                //target temperature set on pa2
  37. #define TARGET_ADC                ADC_AN2                //pa.2=an2
  38. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  39. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  40. //specify led indicators
  41. //we use two leds
  42. //green led - on = target temperature has been reached
  43. //red led - on = heater on (target temperature has not been reached)
  44. #define LED_PORT                PORTA                //port for green led indicators
  45. #define LED_DDR                        TRISA
  46. #define LEDG                        (1<<5)                //green led indicator. comment out if not used
  47. #define LEDR                        (1<<0)                //red led indicator. comment out if not used

  48. #define LOOP_PR                        100                        //loop period, in ms

  49. #define LCD_DEGREEC                1                        //lcd_degree char

  50. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  51. //end hardware configuration

  52. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  53. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  54. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  55. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  56. //celsius / fahrenheit selector
  57. #define C2F_PORT                PORTA
  58. #define C2F_DDR                        TRISA
  59. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  60. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  61. //global variables
  62. unsigned char loop_cnt=0;                        //loop counter
  63. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  64. unsigned short tgt_adc, tgt=0;
  65. unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  66. //for the lcd - lcd16x2
  67. unsigned char vRAM[17];                                //display ram
  68. const unsigned char str0[]="938 Ctrller v1.0";
  69. const unsigned char ver[] ="--version  1.0--";
  70. const unsigned char str1[]="TARGET=    C    ";
  71. const unsigned char str2[]="SENSOR=    C    ";
  72. const unsigned char str3[]="TGT=    /TMP=   ";

  73. const unsigned char lcd_degreeC[]={
  74.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  75. const unsigned char lcd_up[]={
  76.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  77.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  78.         };

  79. #define LCD_UP                        2                                                        //0x01 is special charter
  80.        
  81. //initialize the controller
  82. void ctrl_init(void) {
  83.         HEATER_OFF(HEATER);                                        //turn off heater
  84.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  85.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  86.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  87.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  88.         IO_IN(TARGET_DDR, TARGET);                //target as input
  89.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  90.         adc_init();                                                //reset the adc module
  91.        
  92.         //load up lcd special chacterators
  93.         lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  94.         lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  95. }

  96. //read solder sensors
  97. unsigned short read_sensor(void) {
  98.         //unsigned short tmp;                                //tmp variable
  99.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  100.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  101.         //return ADC2Ohm(tmp);
  102. }


  103. //read the pot that sets the target temperature
  104. //adc 0 -> TARGET_MIN
  105. //adc 1023 -> TARGET_MAX
  106. unsigned short read_target(void) {
  107.         //unsigned short tmp;                                //tmp variable
  108.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  109.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  110. }

  111. //reset the chip
  112. void mcu_init(void) {
  113.         IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  114.        
  115.         ANSEL=0x00;                                                //all pins PORTA
  116.        
  117.         //ANSELH=0x00;

  118.         CMCON0 = 0x07;                                        //turn off analog comparators
  119.         //CM2CON0 = 0x00;

  120. }

  121. //adc the sensors
  122. void ctrl_adc(void) {
  123.         lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  124.         if (lcd_displayC) {        //pin is pulled high -> celsius
  125.                 tmp=read_sensor();                        //read the pot / target temperature
  126.                 tgt=read_target();                        //read temperature sensor,
  127.         } else {                                                //pin is pulled low - fahrenheit
  128.                 tmp=C2F(read_sensor());                        //read the pot / target temperature
  129.                 tgt=C2F(read_target());                        //read temperature sensor,
  130.         }
  131. }

  132. //control the heater
  133. void ctrl_heater(void) {
  134.         //temperature control logic
  135.         if (tmp < tgt) {
  136.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  137.                 HEATER_ON(HEATER);                        //turn on the heater
  138.         } else {
  139.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  140.                 HEATER_OFF(HEATER);                        //turn off the heater
  141.         }

  142. }

  143. //display - 1line format
  144. void ctrl_display1(void) {
  145.         //process line0
  146.         strcpy(vRAM, str3);
  147.         ultoa(&vRAM[4], tgt, 3);
  148.         ultoa(&vRAM[13], tmp, 3);
  149.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  150.         lcd_display(LCD_Line0, vRAM);
  151. }

  152. //display - 2line format
  153. void ctrl_display2(void) {
  154.         //process line0
  155.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  156.         if(lcd_displayC == 0) vRAM[11]='F';
  157.         ultoa(&vRAM[7], tgt, 3);
  158.         ultoa(&vRAM[12], tgt_adc, 4);
  159.         if (tgt > tmp) vRAM[6]=LCD_UP;
  160.         lcd_display(LCD_Line0, vRAM);
  161.                
  162.         //process line1
  163.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  164.         if (lcd_displayC == 0) vRAM[11]='F';
  165.         ultoa(&vRAM[7], tmp, 3);
  166.         ultoa(&vRAM[12], tmp_adc, 4);
  167.         lcd_display(LCD_Line1, vRAM);
  168.        
  169. }

  170. void main(void)
  171. {
  172.         mcu_init();                                                //reset the chip
  173.         lcd_init();                                                //reset the lcd
  174.         ctrl_init();                                        //reset the controller

  175.         //display sign-on message
  176.         strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  177.         strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  178.         delay_ms(1000);

  179.         while (1){
  180.                 //TODO Auto-generated main function

  181.                 //read the tempeature info
  182.                 //HEATER_OFF();                                //turn off the heater
  183.                 //read the sensors
  184.                 ctrl_adc();
  185.                
  186.                 //control the heater
  187.                 ctrl_heater();
  188.                
  189.                 //update display
  190.                 //ctrl_display1();                        //one-line display
  191.                 ctrl_display2();                        //two-line display
  192.                
  193.                 //waste some time
  194.                 delay_ms(LOOP_PR);                //waste some time
  195.         }
  196. }
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-10 07:36:31 | 显示全部楼层
The hex file, ready to be flashed:

  1. :100000005F30840070300B208317753084007E30A1
  2. :100010000B208301132864008001840A040603195D
  3. :10002000003404060C284A232B2592230130A0001B
  4. :100030005F3053235F30A00000303D233430A000F8
  5. :100040005F3053235F30A00040303D23E830A000F4
  6. :100050000330A10070236E25DC23FC256430A00052
  7. :04006000A1012A28A8
  8. :10067A00A10041232008612BA200A401803EE92C9D
  9. :10068A00A600A603260F462B080083160F178F16FF
  10. :10069A000F1291010730831299000800A1008313F9
  11. :1006AA00A20022088400A20A2008A00A09278000C2
  12. :1006BA00800803190800562BA2006A2BA401A40A79
  13. :1006CA00220884000008E924A20A2208840080087B
  14. :1006DA0003190800632B752BC830A200A3017F23DE
  15. :1006EA000130A002031CA103200A0319210A0319DD
  16. :1006FA000800712B2208831345232308A200A301B3
  17. :10070A00882BFF3045230130A202031CA303220ACF
  18. :10071A000319230A03190800862B000000000000B1
  19. :10072A000000851083168510DE3083128505831636
  20. :10073A008505051605158515F5275530A0000130E4
  21. :10074A00C3235D30A0000230C32BA401A501201CE5
  22. :10075A00B42B2208A4070318A50A2308A507031027
  23. :10076A00A20DA30D0310A10CA00C21082004031D47
  24. :10077A00AC2B2508A1002408A0000800A100A401B0
  25. :10078A008313A3000310A30D0310A30D0310230D5D
  26. :10079A004038E924A201A401A40A20082207092753
  27. :1007AA00E924A20A0830220203180800D02B78088C
  28. :1007BA007D02031DE22B77087C020318F02B051437
  29. :1007CA000000000000000000851200000000000088
  30. :1007DA000000851408000510000000000000000059
  31. :1007EA008516000000000000000085100800023095
  32. :1007FA0073273108F6003008F500B701B601013059
  33. :10080A00B5001830B4007508B0007608B100B2011E
  34. :10081A00B3014C240A300310B30CB20CB10CB00C67
  35. :10082A00FF3E031D102C3008C83EA00031080318F3
  36. :10083A00013E003EA1000800A501A60123082204EA
  37. :10084A000319472CA401A40A0310A31B302CA20DE0
  38. :10085A00A30D282C0310A50DA60D23082102031DA4
  39. :10086A00382C22082002031C432C2208A002230849
  40. :10087A00031CA103A1020130A5040310A30CA20CBE
  41. :10088A00A40B2F2C2608A1002508A0000800B801F7
  42. :10089A00B901BA01BB01301C662C3408B807350807
  43. :1008AA0003110318350A031DB90736080311031883
  44. :1008BA00360A031DBA07370803110318370A031D3E
  45. :1008CA00BB070310B40DB50DB60DB70D0310B30C6D
  46. :1008DA00B20CB10CB00C3308320431043004031DDD
  47. :1008EA00502C3B08B3003A08B2003908B100380866
  48. :1008FA00B0000800A500A4032408250784000A30D4
  49. :10090A00AB00AC01AD01AE012308AA002208A90080
  50. :10091A002108A8002008A700B3242708453E092774
  51. :10092A0080000A30B400B501B601B7012308B3004C
  52. :10093A002208B2002108B1002008B000B22533080D
  53. :10094A00A3003208A2003108A1003008A000230841
  54. :10095A0022042104200403190800802C2E082D04E7
  55. :10096A002C042B0403190800AF01AF0AAE1BC32CD9
  56. :10097A000310AB0DAC0DAD0DAE0DBA2C2E082A022C
  57. :10098A00031DD12C2D082902031DD12C2C08280265
  58. :10099A00031DD12C2B082702031CE22C2B08A702CB
  59. :1009AA002C08031C2C0FA8022D08031C2D0FA902CA
  60. :1009BA002E08031C2E0FAA020310AE0CAD0CAC0CB1
  61. :1009CA00AB0CAF0BC32C0800A500A51FEE2C871695
  62. :1009DA00EF2C8712251FF32C0716F42C0712A51EDD
  63. :1009EA00F82C8715F92C8711251EFD2C0714FE2CCF
  64. :1009FA00071000304523A4080319052D0715062DF5
  65. :100A0A0007118714003045238710A51D0E2D871660
  66. :100A1A000F2D8712251D132D0716142D0712A51C3D
  67. :100A2A00182D8715192D8711251C1D2D07141E2D0C
  68. :100A3A00071000304523A4080319252D0715262D74
  69. :100A4A00071187140030452387100800F9308316F0
  70. :100A5A008705C63087050F308312A000A1017023D5
  71. :100A6A0009308704CF3087050030452307118714E2
  72. :100A7A000030452387100530A000A1017023003003
  73. :100A8A00452307118714003045238710C830A20078
  74. :100A9A00A3017F2300304523071187140030452323
  75. :100AAA008710C830A200A3017F2307118715CE3013
  76. :100ABA008705003045230711871400304523871026
  77. :100ACA00A4012B30E924A4010C30E924A401063046
  78. :100ADA00E92C0508F9000830F905F9080319802DF1
  79. :100AEA004C262108FD002008FC00FC232108F80000
  80. :100AFA002008F70008004C262108A1002008A000C1
  81. :100B0A000930A200A301AA232108A1002008A000FD
  82. :100B1A000530A200A30121242008203EFC00210860
  83. :100B2A000318013EFD00FC232108A1002008A000B3
  84. :100B3A000930A200A301AA232108A1002008A000CD
  85. :100B4A000530A200A30121242008203EF700210835
  86. :100B5A000318013E003EF8000800B901BA01BB01C2
  87. :100B6A00BC0137083604350434040319F32DB801DF
  88. :100B7A00B80A0310B71BC72DB40DB50DB60DB70DC6
  89. :100B8A00BD2D0310B90DBA0DBB0DBC0D37083302CC
  90. :100B9A00031DD92D36083202031DD92D350831021D
  91. :100BAA00031DD92D34083002031CED2D3408B00280
  92. :100BBA003508031C350FB1023608031C360FB20282
  93. :100BCA003708031C370FB3020130B9040030031091
  94. :100BDA00B70CB60CB50CB40CB80BC62D3C08B30058
  95. :100BEA003B08B2003A08B1003908B00008001230D8
  96. :100BFA00A0005F305323E901E90AF908031D072E13
  97. :100C0A004630EA000330A4007708A0007808A10063
  98. :100C1A00A201A30166307F240430A4007508A00055
  99. :100C2A007608A100A201A3016B307F2478087D0217
  100. :100C3A00031D212E77087C020318252E0230E500B9
  101. :100C4A005F30A00000303D232330A0005F305323E3
  102. :100C5A00E901E90AF908031D342E4630EA00033097
  103. :100C6A00A4007C08A0007D08A100A201A3016630AF
  104. :100C7A007F240430A4007A08A0007B08A100A20106
  105. :100C8A00A3016B307F245F30A00040303D2B03303E
  106. :100C9A0073273108FB003008FA001930A600A701B3
  107. :100CAA00A801A9010C30AA00FE30AB00FF30AC004D
  108. :100CBA00AD00B701B6010430B500B030B4007A080F
  109. :100CCA00B0007B08B100B201B3014C243308B30071
  110. :100CDA003208B2003108B1003008B000AE01043069
  111. :100CEA00AF007A082E02B4007B08031C7B0A2F028D
  112. :100CFA00B500B601B701B2253008AA0731080318B2
  113. :100D0A00310FAB0732080318320FAC073308031848
  114. :100D1A00330AAD072D08B3002C08B2002B08B10026
  115. :100D2A002A08B000B701B6010130B5007730B40027
  116. :100D3A004C243308B3003208B2003108B10030083D
  117. :100D4A00B000B701B6010230B500BC30B400B2251C
  118. :100D5A003008A60731080318310FA707320803180D
  119. :100D6A00320FA80733080318330AA9072908A50070
  120. :100D7A002808A4002708A3002608A200B701B60184
  121. :100D8A000430B500B030B4007A08B0007B08B10076
  122. :100D9A00B201B3014C243308B3003208B20031085F
  123. :100DAA00B1003008B000A6010430A7007A08260274
  124. :100DBA00B4007B08031C7B0A2702B500B601B70101
  125. :100DCA00B22500303302031DF42E00303202031D17
  126. :100DDA00F42E01303102031DF42EF43030020318D0
  127. :100DEA00FB2E1930A200A301A401A5012308A1002A
  128. :100DFA002208A0000800FE00FE1F082F83137E1899
  129. :100E0A008317000808000408FE0007308A007E08DD
  130. :100E1A008207003439343334383420344334743458
  131. :100E2A0072346C346C346534723420347634313430
  132. :100E3A002E34303400345434413452344734453437
  133. :100E4A0054343D3420342034203420344334203484
  134. :100E5A002034203420340034533445344E3453344F
  135. :100E6A004F3452343D342034203420342034433437
  136. :100E7A00203420342034203400342D342D34763478
  137. :100E8A0065347234733469346F346E3420342034E8
  138. :100E9A0031342E3430342D342D340034303431345E
  139. :100EAA0032343334343435343634373438343934EC
  140. :100EBA006134623463346434653466340734053427
  141. :100ECA0007340034003400340034003404340E345F
  142. :100EDA001F3400341F34003400340034B200AC2F05
  143. :100EEA0083169101910A83121F12922F02308316E0
  144. :100EFA00910083121F12992F0430831691008312D6
  145. :100F0A001F12A02F08308316910083121F12A82FD8
  146. :100F1A0010308316910083121F169F11A12F2030C3
  147. :100F2A008316910083121F169F11A92F4030831632
  148. :100F3A00910083121F169F151F11C72F8030831629
  149. :100F4A00910083121F169F151F15C72FAB2F32084A
  150. :100F5A008313003A0319752F013A03197B2F033AB9
  151. :100F6A000319812F013A0319872F073A03198D2F85
  152. :100F7A00013A0319942F033A03199B2F013A0319D3
  153. :100F8A00A32FAB2F000000000000000000000000AB
  154. :100F9A000000000000000000000000000000000047
  155. :100FAA000000000000000000000000000000000037
  156. :100FBA000000000000000000000000000000000027
  157. :100FCA00000000000000000000009F149F18EB2F93
  158. :100FDA0083121E08B10083161E088312B00008008F
  159. :100FEA001F139F121F1683129F171F139F101F1480
  160. :020FFA000800ED
  161. :02400E00C430BC
  162. :00000001FF
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-10 08:04:03 | 显示全部楼层
The same source code, with minimum changes, running on a 12F675.



Code:

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //Host: 12F675. Minimalist implementation: No LCD, no C2F, ...
  4. //version history for 16F684
  5. //4/07/2013: v0.90 - initial code adapted for 16F684
  6. //code to control a hakko 938/4-wire heater
  7. //with a pot (to control temperature)
  8. //version history
  9. //4/07/2013: v0.90 - initial code integrated
  10. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  11. //4/08/2013: v0.99 - hot-tested display + target temperature setting.
  12. //4/09/2013: v1.00 - fixed sensor temperature overflow issue. First operational release.

  13. #include <htc.h>
  14. #include <string.h>                                        //we use strcpy
  15. #include "config.h"                                        //internal rc oscillator, no clock out
  16. #include "gpio.h"
  17. #include "delay.h"
  18. #include "adc.h"
  19. //#include "lcd_4bit.h"                                //we use lcd4bit
  20. //#include "misc.h"                                        //we use ultoa

  21. //for compatability
  22. #define PORTA                        GPIO
  23. #define TRISA                        TRISIO

  24. //hardware configuration
  25. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  26. #define HEATER_DDR                TRISA
  27. #define HEATER                        (1<<1)                //heater Positive - active high

  28. #define SENSOR_PORT                PORTA                //temperature sensor
  29. #define SENSOR_DDR                TRISA
  30. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  31. #define SENSOR_ADC                ADC_AN3                //pa.4 = an3
  32. #define Vref                        5000ul                //reference voltage for the adc
  33. #define Rm                                1200                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  34. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  35. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  36. #define Temp_Low                25                        //low temp
  37. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  38. #define Temp_High                400                        //high temp
  39. #define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  40. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  41. #define Ohm2Temp(dohm)        (((dohm)<dOhm_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low)))

  42. #define TARGET_PORT                PORTA                //pot to set target temperature
  43. #define TARGET_DDR                TRISA
  44. #define TARGET                        (1<<2)                //target temperature set on pa2
  45. #define TARGET_ADC                ADC_AN2                //pa.2=an2
  46. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  47. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  48. //specify led indicators
  49. //we use two leds
  50. //green led - on = target temperature has been reached
  51. //red led - on = heater on (target temperature has not been reached)
  52. #define LED_PORT                PORTA                //port for green led indicators
  53. #define LED_DDR                        TRISA
  54. #define LEDG                        (1<<5)                //green led indicator. comment out if not used
  55. #define LEDR                        (1<<0)                //red led indicator. comment out if not used

  56. #define LOOP_PR                        100                        //loop period, in ms

  57. #define LCD_DEGREEC                1                        //lcd_degree char

  58. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  59. //end hardware configuration

  60. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  61. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  62. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  63. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  64. //celsius / fahrenheit selector
  65. #define C2F_PORT                PORTA
  66. #define C2F_DDR                        TRISA
  67. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  68. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  69. //global variables
  70. unsigned char loop_cnt=0;                        //loop counter
  71. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  72. unsigned short tgt_adc, tgt=0;
  73. //unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  74. #if 0                                                                //no lcd display
  75. //for the lcd - lcd16x2
  76. unsigned char vRAM[17];                                //display ram
  77. const unsigned char str0[]="938 Ctrller v1.0";
  78. const unsigned char ver[] ="--version  1.0--";
  79. const unsigned char str1[]="TARGET=    C    ";
  80. const unsigned char str2[]="SENSOR=    C    ";
  81. const unsigned char str3[]="TGT=    /TMP=   ";

  82. const unsigned char lcd_degreeC[]={
  83.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  84. const unsigned char lcd_up[]={
  85.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  86.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  87.         };

  88. #define LCD_UP                        2                                                        //0x01 is special charter
  89. #endif
  90.        
  91. //initialize the controller
  92. void ctrl_init(void) {
  93.         HEATER_OFF(HEATER);                                        //turn off heater
  94.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  95.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  96.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  97.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  98.         IO_IN(TARGET_DDR, TARGET);                //target as input
  99.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  100.         adc_init();                                                //reset the adc module
  101.        
  102.         //load up lcd special chacterators
  103.         //lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  104.         //lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  105. }

  106. //read solder sensors
  107. unsigned short read_sensor(void) {
  108.         //unsigned short tmp;                                //tmp variable
  109.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  110.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  111.         //return ADC2Ohm(tmp);
  112. }


  113. //read the pot that sets the target temperature
  114. //adc 0 -> TARGET_MIN
  115. //adc 1023 -> TARGET_MAX
  116. unsigned short read_target(void) {
  117.         //unsigned short tmp;                                //tmp variable
  118.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  119.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  120. }

  121. //reset the chip
  122. void mcu_init(void) {
  123.         //IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  124.        
  125.         ANSEL=0x00;                                                //all pins PORTA
  126.        
  127.         //ANSELH=0x00;

  128.         CMCON = 0x07;                                        //turn off analog comparators
  129.         //CM2CON0 = 0x00;

  130. }

  131. //adc the sensors
  132. void ctrl_adc(void) {
  133.         //lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  134.         //if (lcd_displayC) {        //pin is pulled high -> celsius
  135.                 tmp=read_sensor();                        //read the pot / target temperature
  136.                 tgt=read_target();                        //read temperature sensor,
  137.         //} else {                                                //pin is pulled low - fahrenheit
  138.                 //tmp=C2F(read_sensor());                        //read the pot / target temperature
  139.                 //tgt=C2F(read_target());                        //read temperature sensor,
  140.         //}
  141. }

  142. //control the heater
  143. void ctrl_heater(void) {
  144.         //temperature control logic
  145.         if (tmp < tgt) {
  146.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  147.                 HEATER_ON(HEATER);                        //turn on the heater
  148.         } else {
  149.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  150.                 HEATER_OFF(HEATER);                        //turn off the heater
  151.         }

  152. }

  153. #if 0
  154. //display - 1line format
  155. void ctrl_display1(void) {
  156.         //process line0
  157.         strcpy(vRAM, str3);
  158.         ultoa(&vRAM[4], tgt, 3);
  159.         ultoa(&vRAM[13], tmp, 3);
  160.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  161.         lcd_display(LCD_Line0, vRAM);
  162. }

  163. //display - 2line format
  164. void ctrl_display2(void) {
  165.         //process line0
  166.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  167.         if(lcd_displayC == 0) vRAM[11]='F';
  168.         ultoa(&vRAM[7], tgt, 3);
  169.         ultoa(&vRAM[12], tgt_adc, 4);
  170.         if (tgt > tmp) vRAM[6]=LCD_UP;
  171.         lcd_display(LCD_Line0, vRAM);
  172.                
  173.         //process line1
  174.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  175.         if (lcd_displayC == 0) vRAM[11]='F';
  176.         ultoa(&vRAM[7], tmp, 3);
  177.         ultoa(&vRAM[12], tmp_adc, 4);
  178.         lcd_display(LCD_Line1, vRAM);
  179.        
  180. }
  181. #endif

  182. void main(void)
  183. {
  184.         mcu_init();                                                //reset the chip
  185.         //lcd_init();                                                //reset the lcd
  186.         ctrl_init();                                        //reset the controller

  187.         //display sign-on message
  188.         //strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  189.         //strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  190.         delay_ms(1000);

  191.         while (1){
  192.                 //TODO Auto-generated main function

  193.                 //read the tempeature info
  194.                 //HEATER_OFF();                                //turn off the heater
  195.                 //read the sensors
  196.                 ctrl_adc();
  197.                
  198.                 //control the heater
  199.                 ctrl_heater();
  200.                
  201.                 //update display
  202.                 //ctrl_display1();                        //one-line display
  203.                 //ctrl_display2();                        //two-line display
  204.                
  205.                 //waste some time
  206.                 delay_ms(LOOP_PR);                //waste some time
  207.         }
  208. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-10 08:07:06 | 显示全部楼层
本帖最后由 millwood0 于 2013-4-10 08:09 编辑
running on a 12F675.


Total part count:

1k resistor x 4 (at least two optional);
120ohm resistor x 1 (user specified);
0.1uf cap x 1;
12F675 x 1;
5v regulator (78L05 or equivalent) x 1;
FDP3672 (or equivalent mosfet) x 1;
LED (optional) x 2;
Pot x 1;

That's all it takes to build a controller to drive a 907 handle. You can probably build one without using a pcb.

出0入0汤圆

 楼主| 发表于 2013-4-10 08:34:31 | 显示全部楼层
BTW, with minor modification, the code here can be rewritten to drive handles using 2-wire heaters.

出0入0汤圆

发表于 2013-4-12 00:23:37 | 显示全部楼层
瞬间感到,无地自容……今夜注定难眠

出0入0汤圆

 楼主| 发表于 2013-4-12 07:14:32 | 显示全部楼层
Running the code on an attiny85:



It should work on any 8pdip attiny.

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //Host: 12F675. Minimalist implementation: No LCD, no C2F, ...
  4. //version history for 16F684
  5. //4/07/2013: v0.90 - initial code adapted for 16F684
  6. //code to control a hakko 938/4-wire heater
  7. //with a pot (to control temperature)
  8. //version history
  9. //4/07/2013: v0.90 - initial code integrated
  10. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  11. //4/08/2013: v0.99 - hot-tested display + target temperature setting.
  12. //4/09/2013: v1.00 - fixed sensor temperature overflow issue. First operational release.

  13. //#include <htc.h>                                        //we use picc
  14. #include <avr/io.h>                                        //we use gcc-avr
  15. #include <string.h>                                        //we use strcpy
  16. //#include "config.h"                                        //internal rc oscillator, no clock out
  17. #include "gpio.h"
  18. #include "delay.h"
  19. #include "adc.h"
  20. //#include "lcd_4bit.h"                                //we use lcd4bit
  21. //#include "misc.h"                                        //we use ultoa

  22. //for compatability
  23. #define PORTA                        PORTB
  24. #define TRISA                        DDRB

  25. //hardware configuration
  26. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  27. #define HEATER_DDR                TRISA
  28. #define HEATER                        (1<<1)                //heater Positive - active high

  29. #define SENSOR_PORT                PORTA                //temperature sensor
  30. #define SENSOR_DDR                TRISA
  31. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  32. #define SENSOR_ADC                ADC_ADMUX_ADC2                //pa.4 = an3
  33. #define Vref                        5000ul                //reference voltage for the adc
  34. #define Rm                                1200                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  35. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  36. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  37. #define Temp_Low                25                        //low temp
  38. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  39. #define Temp_High                400                        //high temp
  40. #define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  41. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  42. #define Ohm2Temp(dohm)        (((dohm)<dOhm_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low)))

  43. #define TARGET_PORT                PORTA                //pot to set target temperature
  44. #define TARGET_DDR                TRISA
  45. #define TARGET                        (1<<2)                //target temperature set on pa2
  46. #define TARGET_ADC                ADC_ADMUX_ADC1                //pa.2=an2
  47. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  48. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  49. //specify led indicators
  50. //we use two leds
  51. //green led - on = target temperature has been reached
  52. //red led - on = heater on (target temperature has not been reached)
  53. #define LED_PORT                PORTA                //port for green led indicators
  54. #define LED_DDR                        TRISA
  55. #define LEDG                        (1<<5)                //green led indicator. comment out if not used
  56. #define LEDR                        (1<<0)                //red led indicator. comment out if not used

  57. #define LOOP_PR                        100                        //loop period, in ms

  58. #define LCD_DEGREEC                1                        //lcd_degree char

  59. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  60. //end hardware configuration

  61. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  62. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  63. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  64. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  65. //celsius / fahrenheit selector
  66. #define C2F_PORT                PORTA
  67. #define C2F_DDR                        TRISA
  68. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  69. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  70. //global variables
  71. unsigned char loop_cnt=0;                        //loop counter
  72. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  73. unsigned short tgt_adc, tgt=0;
  74. //unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  75. #if 0                                                                //no lcd display
  76. //for the lcd - lcd16x2
  77. unsigned char vRAM[17];                                //display ram
  78. const unsigned char str0[]="938 Ctrller v1.0";
  79. const unsigned char ver[] ="--version  1.0--";
  80. const unsigned char str1[]="TARGET=    C    ";
  81. const unsigned char str2[]="SENSOR=    C    ";
  82. const unsigned char str3[]="TGT=    /TMP=   ";

  83. const unsigned char lcd_degreeC[]={
  84.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  85. const unsigned char lcd_up[]={
  86.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  87.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  88.         };

  89. #define LCD_UP                        2                                                        //0x01 is special charter
  90. #endif

  91. //initialize the controller
  92. void ctrl_init(void) {
  93.         HEATER_OFF(HEATER);                                        //turn off heater
  94.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  95.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  96.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  97.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  98.         IO_IN(TARGET_DDR, TARGET);                //target as input
  99.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  100.         adc_init();                                                //reset the adc module

  101.         //load up lcd special chacterators
  102.         //lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  103.         //lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  104. }

  105. //read solder sensors
  106. unsigned short read_sensor(void) {
  107.         //unsigned short tmp;                                //tmp variable
  108.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  109.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  110.         //return ADC2Ohm(tmp);
  111. }


  112. //read the pot that sets the target temperature
  113. //adc 0 -> TARGET_MIN
  114. //adc 1023 -> TARGET_MAX
  115. unsigned short read_target(void) {
  116.         //unsigned short tmp;                                //tmp variable
  117.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  118.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  119. }

  120. //reset the chip
  121. void mcu_init(void) {
  122.         //IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz

  123.         //ANSEL=0x00;                                                //all pins PORTA

  124.         //ANSELH=0x00;

  125.         //CMCON = 0x07;                                        //turn off analog comparators
  126.         //CM2CON0 = 0x00;

  127. }

  128. //adc the sensors
  129. void ctrl_adc(void) {
  130.         //lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  131.         //if (lcd_displayC) {        //pin is pulled high -> celsius
  132.                 tmp=read_sensor();                        //read the pot / target temperature
  133.                 tgt=read_target();                        //read temperature sensor,
  134.         //} else {                                                //pin is pulled low - fahrenheit
  135.                 //tmp=C2F(read_sensor());                        //read the pot / target temperature
  136.                 //tgt=C2F(read_target());                        //read temperature sensor,
  137.         //}
  138. }

  139. //control the heater
  140. void ctrl_heater(void) {
  141.         //temperature control logic
  142.         if (tmp < tgt) {
  143.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  144.                 HEATER_ON(HEATER);                        //turn on the heater
  145.         } else {
  146.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  147.                 HEATER_OFF(HEATER);                        //turn off the heater
  148.         }

  149. }

  150. #if 0
  151. //display - 1line format
  152. void ctrl_display1(void) {
  153.         //process line0
  154.         strcpy(vRAM, str3);
  155.         ultoa(&vRAM[4], tgt, 3);
  156.         ultoa(&vRAM[13], tmp, 3);
  157.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  158.         lcd_display(LCD_Line0, vRAM);
  159. }

  160. //display - 2line format
  161. void ctrl_display2(void) {
  162.         //process line0
  163.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  164.         if(lcd_displayC == 0) vRAM[11]='F';
  165.         ultoa(&vRAM[7], tgt, 3);
  166.         ultoa(&vRAM[12], tgt_adc, 4);
  167.         if (tgt > tmp) vRAM[6]=LCD_UP;
  168.         lcd_display(LCD_Line0, vRAM);

  169.         //process line1
  170.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  171.         if (lcd_displayC == 0) vRAM[11]='F';
  172.         ultoa(&vRAM[7], tmp, 3);
  173.         ultoa(&vRAM[12], tmp_adc, 4);
  174.         lcd_display(LCD_Line1, vRAM);

  175. }
  176. #endif

  177. int main(void)
  178. {
  179.         mcu_init();                                                //reset the chip
  180.         //lcd_init();                                                //reset the lcd
  181.         ctrl_init();                                        //reset the controller

  182.         //display sign-on message
  183.         //strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  184.         //strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  185.         delay_ms(1000);

  186.         while (1){
  187.                 //TODO Auto-generated main function

  188.                 //read the tempeature info
  189.                 //HEATER_OFF();                                //turn off the heater
  190.                 //read the sensors
  191.                 ctrl_adc();

  192.                 //control the heater
  193.                 ctrl_heater();

  194.                 //update display
  195.                 //ctrl_display1();                        //one-line display
  196.                 //ctrl_display2();                        //two-line display

  197.                 //waste some time
  198.                 delay_ms(LOOP_PR);                //waste some time
  199.         }
  200. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-12 07:16:36 | 显示全部楼层
Here is the hex file, in case you want to burn it:

  1. :100000000EC01DC01CC01BC01AC019C018C017C02C
  2. :1000100016C015C014C013C012C011C010C01124E6
  3. :100020001FBECFE5D2E0DEBFCDBF10E0A0E6B0E05E
  4. :1000300001C01D92A936B107E1F7B3D136C2E0CFB6
  5. :10004000DF93CF9300D0CDB7DEB7898389818A83D0
  6. :100050008A81882311F081E08A838A819981915075
  7. :100060009983882399F70F900F90CF91DF9108958E
  8. :10007000DF93CF9300D00F92CDB7DEB79A838983F9
  9. :100080008981DEDF89819A81892F99279A838983E3
  10. :1000900002C08FEFD5DF1B8289819A81009711F012
  11. :1000A00081E08B8389819A8101979A8389838B81EF
  12. :1000B000882379F70F900F900F90CF91DF910895DB
  13. :1000C000DF93CF9300D00F92CDB7DEB79A838983A9
  14. :1000D00003C080E892E0CCDF1B8289819A8100977F
  15. :1000E00011F081E08B8389819A8101979A838983BA
  16. :1000F0008B81882371F70F900F900F90CF91DF9134
  17. :100100000895DF93CF93CDB7DEB700000000000065
  18. :100110000000A8E3B0E0E8E3F0E080818D7F8C93FD
  19. :10012000A7E3B0E0E7E3F0E0808182608C93A8E38E
  20. :10013000B0E0E8E3F0E080818E7D8C93A7E3B0E04F
  21. :10014000E7E3F0E0808181628C93A7E3B0E0E7E32E
  22. :10015000F0E080818F7E8C93A7E3B0E0E7E3F0E0EE
  23. :1001600080818B7F8C93A7E3B0E0E7E3F0E08081B0
  24. :10017000877F8C9325D1CF91DF910895EF92FF92E5
  25. :100180000F931F93DF93CF9300D0CDB7DEB782E0FC
  26. :1001900028D19093660080936500809165009091CE
  27. :1001A0006600CC01A0E0B0E0BC01CD0120EB34E062
  28. :1001B00040E050E03FD1DC01CB017C018D0120917A
  29. :1001C00065003091660080E094E0821B930B9C01F7
  30. :1001D00040E050E0C801B70146D1DA01C901843FCF
  31. :1001E00021E0920720E0A20720E0B207F0F1809121
  32. :1001F000650090916600CC01A0E0B0E0BC01CD01AB
  33. :1002000020EB34E040E050E015D1DC01CB017C0173
  34. :100210008D01209165003091660080E094E0821BA2
  35. :10022000930B9C0140E050E0C801B7011CD1DA01FA
  36. :10023000C901BC01CD0127E731E040E050E0FAD030
  37. :10024000DC01CB018C569C4DA240B0402CEB32E03F
  38. :1002500040E050E0BC01CD0106D1DA01C9019C01AA
  39. :10026000275E3F4F3A83298304C089E190E09A8357
  40. :10027000898389819A810F900F90CF91DF911F918F
  41. :100280000F91FF90EF900895DF93CF93CDB7DEB736
  42. :1002900081E0A7D090936800809367008091670009
  43. :1002A00090916800CC01A0E0B0E0BC01CD0128E154
  44. :1002B00031E040E050E0BED0DC01CB01072E7AE017
  45. :1002C000B695A795979587957A95D1F7702D885310
  46. :1002D0009F4FCF91DF910895DF93CF93CDB7DEB7D6
  47. :1002E000CF91DF910895DF93CF93CDB7DEB746DF8F
  48. :1002F0009093620080936100C7DF909364008093C5
  49. :100300006300CF91DF910895DF93CF93CDB7DEB730
  50. :1003100020916100309162008091630090916400AF
  51. :1003200028173907F0F4A8E3B0E0E8E3F0E08081B3
  52. :1003300081608C930000000000000000A8E3B0E0A2
  53. :10034000E8E3F0E080818F7D8C93000000000000E6
  54. :100350000000A8E3B0E0E8E3F0E0808182608C93E5
  55. :100360001DC0A8E3B0E0E8E3F0E080818E7F8C93CD
  56. :100370000000000000000000A8E3B0E0E8E3F0E0C7
  57. :10038000808180628C930000000000000000A8E3E0
  58. :10039000B0E0E8E3F0E080818D7F8C93CF91DF9136
  59. :1003A0000895DF93CF93CDB7DEB796DFAADE88EE50
  60. :1003B00093E086DE98DFA8DF84E690E081DEFACF66
  61. :1003C000DF93CF93CDB7DEB7E7E2F0E01082E6E24D
  62. :1003D000F0E087E88083E3E2F0E01082CF91DF91E4
  63. :1003E0000895DF93CF930F92CDB7DEB78983A7E24D
  64. :1003F000B0E0E7E2F0E08081982F907E89818F71F4
  65. :10040000892B8C93A6E2B0E0E6E2F0E08081806484
  66. :100410008C93E6E2F0E08081882F90E08074907009
  67. :100420000097B9F7E4E2F0E0808191810F90CF91DD
  68. :10043000DF910895FF27EE27BB27AA2760FF04C09E
  69. :10044000A20FB31FE41FF51F220F331F441F551FB8
  70. :10045000969587957795679589F70097760771F751
  71. :10046000CF01BD010895A1E21A2EAA1BBB1BFD01FD
  72. :100470000DC0AA1FBB1FEE1FFF1FA217B307E40783
  73. :10048000F50720F0A21BB30BE40BF50B661F771FDB
  74. :10049000881F991F1A9469F76095709580959095BB
  75. :0E04A0009B01AC01BD01CF010895F894FFCF80
  76. :00000001FF
复制代码
fuse settings: internal rc oscillator, divide by 8, reset disabled.

I didn't run it on real hardware so try it at your own risk.

出0入0汤圆

 楼主| 发表于 2013-4-15 02:54:59 | 显示全部楼层
I finished building a version of the hakko controller on 16F684 + LCD.

Great success and the unit is fully functional.

A few things:

1) the leds turn out to be too bright. I should have used higher R5/R6 -> now they are 1k resistors.
2) fakko vs. hakko: the original code runs fine on a genuine hakko. Fake hakko handles (fakkos) appear to run slightly higher resistance at the same temperature so under the stock software, the fakkos run cooler. Posted below is the code for running a fakko handle.

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //version history
  4. //4/07/2013: v0.90 - initial code integrated
  5. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  6. //4/08/2013: v0.99 - hot-tested display + target temperature setting.
  7. //4/09/2013: v1.00 - fixed sensor temperature overflow issue. First operational release.
  8. //4/14/2013: v1.10 - adjusted temperature curve for fake Hakko

  9. #include <htc.h>
  10. #include <string.h>                                        //we use strcpy
  11. #include "config.h"                                        //internal rc oscillator, no clock out
  12. #include "gpio.h"
  13. #include "delay.h"
  14. #include "adc.h"
  15. #include "lcd_4bit.h"                                //we use lcd4bit
  16. #include "misc.h"                                        //we use ultoa

  17. //hardware configuration
  18. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  19. #define HEATER_DDR                TRISA
  20. #define HEATER                        (1<<1)                //heater Positive - active high

  21. #define SENSOR_PORT                PORTA                //temperature sensor
  22. #define SENSOR_DDR                TRISA
  23. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  24. #define SENSOR_ADC                ADC_AN3                //pa.4 = an3
  25. #define Vref                        5000ul                //reference voltage for the adc
  26. #define Rm                                1200                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  27. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  28. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  29. #define Temp_Low                25                        //low temp
  30. //for genuine and fake hakko handles
  31. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  32. #define Temp_High                400                        //high temp
  33. //for genuine hakkko handles
  34. //#define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  35. //for fake hakkko handles
  36. #define dOhm_at_High        1700                //ptc resistance (in ohm) at Temp_High
  37. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  38. #define Ohm2Temp(dohm)        (((dohm)<dOhm_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low)))

  39. #define TARGET_PORT                PORTA                //pot to set target temperature
  40. #define TARGET_DDR                TRISA
  41. #define TARGET                        (1<<2)                //target temperature set on pa2
  42. #define TARGET_ADC                ADC_AN2                //pa.2=an2
  43. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  44. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  45. //specify led indicators
  46. //we use two leds
  47. //green led - on = target temperature has been reached
  48. //red led - on = heater on (target temperature has not been reached)
  49. #define LED_PORT                PORTA                //port for green led indicators
  50. #define LED_DDR                        TRISA
  51. #define LEDG                        (1<<5)                //green led indicator. comment out if not used
  52. #define LEDR                        (1<<0)                //red led indicator. comment out if not used

  53. #define LOOP_PR                        100                        //loop period, in ms

  54. #define LCD_DEGREEC                1                        //lcd_degree char

  55. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  56. //end hardware configuration

  57. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  58. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  59. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  60. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  61. //celsius / fahrenheit selector
  62. #define C2F_PORT                PORTA
  63. #define C2F_DDR                        TRISA
  64. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  65. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  66. //global variables
  67. unsigned char loop_cnt=0;                        //loop counter
  68. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  69. unsigned short tgt_adc, tgt=0;
  70. unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  71. //for the lcd - lcd16x2
  72. unsigned char vRAM[17];                                //display ram
  73. const unsigned char str0[]="938 Ctrller v1.0";
  74. const unsigned char ver[] ="--version  1.0--";
  75. const unsigned char str1[]="TARGET=    C    ";
  76. const unsigned char str2[]="SENSOR=    C    ";
  77. const unsigned char str3[]="TGT=    /TMP=   ";

  78. const unsigned char lcd_degreeC[]={
  79.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  80. const unsigned char lcd_up[]={
  81.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  82.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  83.         };

  84. #define LCD_UP                        2                                                        //0x01 is special charter
  85.        
  86. //initialize the controller
  87. void ctrl_init(void) {
  88.         HEATER_OFF(HEATER);                                        //turn off heater
  89.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  90.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  91.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  92.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  93.         IO_IN(TARGET_DDR, TARGET);                //target as input
  94.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  95.         adc_init();                                                //reset the adc module
  96.        
  97.         //load up lcd special chacterators
  98.         lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  99.         lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  100. }

  101. //read solder sensors
  102. unsigned short read_sensor(void) {
  103.         //unsigned short tmp;                                //tmp variable
  104.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  105.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  106.         //return ADC2Ohm(tmp);
  107. }


  108. //read the pot that sets the target temperature
  109. //adc 0 -> TARGET_MIN
  110. //adc 1023 -> TARGET_MAX
  111. unsigned short read_target(void) {
  112.         //unsigned short tmp;                                //tmp variable
  113.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  114.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  115. }

  116. //reset the chip
  117. void mcu_init(void) {
  118.         IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  119.        
  120.         ANSEL=0x00;                                                //all pins PORTA
  121.        
  122.         //ANSELH=0x00;

  123.         CMCON0 = 0x07;                                        //turn off analog comparators
  124.         //CM2CON0 = 0x00;

  125. }

  126. //adc the sensors
  127. void ctrl_adc(void) {
  128.         lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  129.         if (lcd_displayC) {        //pin is pulled high -> celsius
  130.                 tmp=read_sensor();                        //read the pot / target temperature
  131.                 tgt=read_target();                        //read temperature sensor,
  132.         } else {                                                //pin is pulled low - fahrenheit
  133.                 tmp=C2F(read_sensor());                        //read the pot / target temperature
  134.                 tgt=C2F(read_target());                        //read temperature sensor,
  135.         }
  136. }

  137. //control the heater
  138. void ctrl_heater(void) {
  139.         //temperature control logic
  140.         if (tmp < tgt) {
  141.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  142.                 HEATER_ON(HEATER);                        //turn on the heater
  143.         } else {
  144.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  145.                 HEATER_OFF(HEATER);                        //turn off the heater
  146.         }

  147. }

  148. //display - 1line format
  149. void ctrl_display1(void) {
  150.         //process line0
  151.         strcpy(vRAM, str3);
  152.         ultoa(&vRAM[4], tgt, 3);
  153.         ultoa(&vRAM[13], tmp, 3);
  154.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  155.         lcd_display(LCD_Line0, vRAM);
  156. }

  157. //display - 2line format
  158. void ctrl_display2(void) {
  159.         //process line0
  160.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  161.         if(lcd_displayC == 0) vRAM[11]='F';
  162.         ultoa(&vRAM[7], tgt, 3);
  163.         ultoa(&vRAM[12], tgt_adc, 4);
  164.         if (tgt > tmp) vRAM[6]=LCD_UP;
  165.         lcd_display(LCD_Line0, vRAM);
  166.                
  167.         //process line1
  168.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  169.         if (lcd_displayC == 0) vRAM[11]='F';
  170.         ultoa(&vRAM[7], tmp, 3);
  171.         ultoa(&vRAM[12], tmp_adc, 4);
  172.         lcd_display(LCD_Line1, vRAM);
  173.        
  174. }

  175. void main(void)
  176. {
  177.         mcu_init();                                                //reset the chip
  178.         lcd_init();                                                //reset the lcd
  179.         ctrl_init();                                        //reset the controller

  180.         //display sign-on message
  181.         strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  182.         strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  183.         delay_ms(1000);

  184.         while (1){
  185.                 //TODO Auto-generated main function

  186.                 //read the tempeature info
  187.                 //HEATER_OFF();                                //turn off the heater
  188.                 //read the sensors
  189.                 ctrl_adc();
  190.                
  191.                 //control the heater
  192.                 ctrl_heater();
  193.                
  194.                 //update display
  195.                 //ctrl_display1();                        //one-line display
  196.                 ctrl_display2();                        //two-line display
  197.                
  198.                 //waste some time
  199.                 delay_ms(LOOP_PR);                //waste some time
  200.         }
  201. }
复制代码
3) gain control. Originally I didn't contemplate any gain control - it was done in software and not terribly convenient. My fakko experience suggests that it best that some form of gain control be available so the user doesn't have to reprogram the software for different handles.

As such, here is the schematic with gain control:



RV2 and R7 form the gain control circuit: it attenuates the voltage divider. Adjusting RV2 down towards the bottom allows the user to run the handle hotter. The adjust range, as designed, is about 100c. The adjustment procedure is the same as in the stock Hakko manual: turn the target temperature to 400c and adjust RV2 until the desired temperature is reached.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-15 02:56:12 | 显示全部楼层
For those wanting to build it, here is the hex file for 16F684:
  1. :100000005F30840070300B208317753084007E30A1
  2. :100010000B208301132864008001840A040603195D
  3. :10002000003404060C284A232B2592230130A0001B
  4. :100030005F3053235F30A00000303D233430A000F8
  5. :100040005F3053235F30A00040303D23E830A000F4
  6. :100050000330A10070236E25DC23FC256430A00052
  7. :04006000A1012A28A8
  8. :10067A00A10041232008612BA200A401803EE92C9D
  9. :10068A00A600A603260F462B080083160F178F16FF
  10. :10069A000F1291010730831299000800A1008313F9
  11. :1006AA00A20022088400A20A2008A00A09278000C2
  12. :1006BA00800803190800562BA2006A2BA401A40A79
  13. :1006CA00220884000008E924A20A2208840080087B
  14. :1006DA0003190800632B752BC830A200A3017F23DE
  15. :1006EA000130A002031CA103200A0319210A0319DD
  16. :1006FA000800712B2208831345232308A200A301B3
  17. :10070A00882BFF3045230130A202031CA303220ACF
  18. :10071A000319230A03190800862B000000000000B1
  19. :10072A000000851083168510DE3083128505831636
  20. :10073A008505051605158515F5275530A0000130E4
  21. :10074A00C3235D30A0000230C32BA401A501201CE5
  22. :10075A00B42B2208A4070318A50A2308A507031027
  23. :10076A00A20DA30D0310A10CA00C21082004031D47
  24. :10077A00AC2B2508A1002408A0000800A100A401B0
  25. :10078A008313A3000310A30D0310A30D0310230D5D
  26. :10079A004038E924A201A401A40A20082207092753
  27. :1007AA00E924A20A0830220203180800D02B78088C
  28. :1007BA007D02031DE22B77087C020318F02B051437
  29. :1007CA000000000000000000851200000000000088
  30. :1007DA000000851408000510000000000000000059
  31. :1007EA008516000000000000000085100800023095
  32. :1007FA0073273108F6003008F500B701B601013059
  33. :10080A00B5001830B4007508B0007608B100B2011E
  34. :10081A00B3014C240A300310B30CB20CB10CB00C67
  35. :10082A00FF3E031D102C3008C83EA00031080318F3
  36. :10083A00013E003EA1000800A501A60123082204EA
  37. :10084A000319472CA401A40A0310A31B302CA20DE0
  38. :10085A00A30D282C0310A50DA60D23082102031DA4
  39. :10086A00382C22082002031C432C2208A002230849
  40. :10087A00031CA103A1020130A5040310A30CA20CBE
  41. :10088A00A40B2F2C2608A1002508A0000800B801F7
  42. :10089A00B901BA01BB01301C662C3408B807350807
  43. :1008AA0003110318350A031DB90736080311031883
  44. :1008BA00360A031DBA07370803110318370A031D3E
  45. :1008CA00BB070310B40DB50DB60DB70D0310B30C6D
  46. :1008DA00B20CB10CB00C3308320431043004031DDD
  47. :1008EA00502C3B08B3003A08B2003908B100380866
  48. :1008FA00B0000800A500A4032408250784000A30D4
  49. :10090A00AB00AC01AD01AE012308AA002208A90080
  50. :10091A002108A8002008A700B3242708453E092774
  51. :10092A0080000A30B400B501B601B7012308B3004C
  52. :10093A002208B2002108B1002008B000B22533080D
  53. :10094A00A3003208A2003108A1003008A000230841
  54. :10095A0022042104200403190800802C2E082D04E7
  55. :10096A002C042B0403190800AF01AF0AAE1BC32CD9
  56. :10097A000310AB0DAC0DAD0DAE0DBA2C2E082A022C
  57. :10098A00031DD12C2D082902031DD12C2C08280265
  58. :10099A00031DD12C2B082702031CE22C2B08A702CB
  59. :1009AA002C08031C2C0FA8022D08031C2D0FA902CA
  60. :1009BA002E08031C2E0FAA020310AE0CAD0CAC0CB1
  61. :1009CA00AB0CAF0BC32C0800A500A51FEE2C871695
  62. :1009DA00EF2C8712251FF32C0716F42C0712A51EDD
  63. :1009EA00F82C8715F92C8711251EFD2C0714FE2CCF
  64. :1009FA00071000304523A4080319052D0715062DF5
  65. :100A0A0007118714003045238710A51D0E2D871660
  66. :100A1A000F2D8712251D132D0716142D0712A51C3D
  67. :100A2A00182D8715192D8711251C1D2D07141E2D0C
  68. :100A3A00071000304523A4080319252D0715262D74
  69. :100A4A00071187140030452387100800F9308316F0
  70. :100A5A008705C63087050F308312A000A1017023D5
  71. :100A6A0009308704CF3087050030452307118714E2
  72. :100A7A000030452387100530A000A1017023003003
  73. :100A8A00452307118714003045238710C830A20078
  74. :100A9A00A3017F2300304523071187140030452323
  75. :100AAA008710C830A200A3017F2307118715CE3013
  76. :100ABA008705003045230711871400304523871026
  77. :100ACA00A4012B30E924A4010C30E924A401063046
  78. :100ADA00E92C0508F9000830F905F9080319802DF1
  79. :100AEA004C262108FD002008FC00FC232108F80000
  80. :100AFA002008F70008004C262108A1002008A000C1
  81. :100B0A000930A200A301AA232108A1002008A000FD
  82. :100B1A000530A200A30121242008203EFC00210860
  83. :100B2A000318013EFD00FC232108A1002008A000B3
  84. :100B3A000930A200A301AA232108A1002008A000CD
  85. :100B4A000530A200A30121242008203EF700210835
  86. :100B5A000318013E003EF8000800B901BA01BB01C2
  87. :100B6A00BC0137083604350434040319F32DB801DF
  88. :100B7A00B80A0310B71BC72DB40DB50DB60DB70DC6
  89. :100B8A00BD2D0310B90DBA0DBB0DBC0D37083302CC
  90. :100B9A00031DD92D36083202031DD92D350831021D
  91. :100BAA00031DD92D34083002031CED2D3408B00280
  92. :100BBA003508031C350FB1023608031C360FB20282
  93. :100BCA003708031C370FB3020130B9040030031091
  94. :100BDA00B70CB60CB50CB40CB80BC62D3C08B30058
  95. :100BEA003B08B2003A08B1003908B00008001230D8
  96. :100BFA00A0005F305323E901E90AF908031D072E13
  97. :100C0A004630EA000330A4007708A0007808A10063
  98. :100C1A00A201A30166307F240430A4007508A00055
  99. :100C2A007608A100A201A3016B307F2478087D0217
  100. :100C3A00031D212E77087C020318252E0230E500B9
  101. :100C4A005F30A00000303D232330A0005F305323E3
  102. :100C5A00E901E90AF908031D342E4630EA00033097
  103. :100C6A00A4007C08A0007D08A100A201A3016630AF
  104. :100C7A007F240430A4007A08A0007B08A100A20106
  105. :100C8A00A3016B307F245F30A00040303D2B03303E
  106. :100C9A0073273108FB003008FA001930A600A701B3
  107. :100CAA00A801A9010C30AA00FE30AB00FF30AC004D
  108. :100CBA00AD00B701B6010430B500B030B4007A080F
  109. :100CCA00B0007B08B100B201B3014C243308B30071
  110. :100CDA003208B2003108B1003008B000AE01043069
  111. :100CEA00AF007A082E02B4007B08031C7B0A2F028D
  112. :100CFA00B500B601B701B2253008AA0731080318B2
  113. :100D0A00310FAB0732080318320FAC073308031848
  114. :100D1A00330AAD072D08B3002C08B2002B08B10026
  115. :100D2A002A08B000B701B6010130B5007730B40027
  116. :100D3A004C243308B3003208B2003108B10030083D
  117. :100D4A00B000B701B6010430B500B030B400B22526
  118. :100D5A003008A60731080318310FA707320803180D
  119. :100D6A00320FA80733080318330AA9072908A50070
  120. :100D7A002808A4002708A3002608A200B701B60184
  121. :100D8A000430B500B030B4007A08B0007B08B10076
  122. :100D9A00B201B3014C243308B3003208B20031085F
  123. :100DAA00B1003008B000A6010430A7007A08260274
  124. :100DBA00B4007B08031C7B0A2702B500B601B70101
  125. :100DCA00B22500303302031DF42E00303202031D17
  126. :100DDA00F42E01303102031DF42EF43030020318D0
  127. :100DEA00FB2E1930A200A301A401A5012308A1002A
  128. :100DFA002208A0000800FE00FE1F082F83137E1899
  129. :100E0A008317000808000408FE0007308A007E08DD
  130. :100E1A008207003439343334383420344334743458
  131. :100E2A0072346C346C346534723420347634313430
  132. :100E3A002E34303400345434413452344734453437
  133. :100E4A0054343D3420342034203420344334203484
  134. :100E5A002034203420340034533445344E3453344F
  135. :100E6A004F3452343D342034203420342034433437
  136. :100E7A00203420342034203400342D342D34763478
  137. :100E8A0065347234733469346F346E3420342034E8
  138. :100E9A0031342E3430342D342D340034303431345E
  139. :100EAA0032343334343435343634373438343934EC
  140. :100EBA006134623463346434653466340734053427
  141. :100ECA0007340034003400340034003404340E345F
  142. :100EDA001F3400341F34003400340034B200AC2F05
  143. :100EEA0083169101910A83121F12922F02308316E0
  144. :100EFA00910083121F12992F0430831691008312D6
  145. :100F0A001F12A02F08308316910083121F12A82FD8
  146. :100F1A0010308316910083121F169F11A12F2030C3
  147. :100F2A008316910083121F169F11A92F4030831632
  148. :100F3A00910083121F169F151F11C72F8030831629
  149. :100F4A00910083121F169F151F15C72FAB2F32084A
  150. :100F5A008313003A0319752F013A03197B2F033AB9
  151. :100F6A000319812F013A0319872F073A03198D2F85
  152. :100F7A00013A0319942F033A03199B2F013A0319D3
  153. :100F8A00A32FAB2F000000000000000000000000AB
  154. :100F9A000000000000000000000000000000000047
  155. :100FAA000000000000000000000000000000000037
  156. :100FBA000000000000000000000000000000000027
  157. :100FCA00000000000000000000009F149F18EB2F93
  158. :100FDA0083121E08B10083161E088312B00008008F
  159. :100FEA001F139F121F1683129F171F139F101F1480
  160. :020FFA000800ED
  161. :02400E00C430BC
  162. :00000001FF
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-15 02:57:54 | 显示全部楼层
I am building the 12F675 version (simplified circuit, no lcd, no C/F conversion) and once I have it done, I will repost the code + hex files as well.

enjoy.

出0入0汤圆

 楼主| 发表于 2013-4-15 07:15:25 | 显示全部楼层
I am building the 12F675 version


Done!

Just finished assembling the 12f675-based controller.

Here is the schematic:



Notice slightly different wiring (due to my layout), vs. the 16F684 version.

the code:

  1. //code to control a hakko 938/4-wire heater
  2. //with a pot (to control temperature)
  3. //Host: 12F675. Minimalist implementation: No LCD, no C2F, ...
  4. //version history for 16F684
  5. //4/07/2013: v0.90 - initial code adapted for 16F684
  6. //code to control a hakko 938/4-wire heater
  7. //with a pot (to control temperature)
  8. //version history
  9. //4/07/2013: v0.90 - initial code integrated
  10. //4/07/2013: v0.97 - added Celsius / Fahrenheit conversion
  11. //4/08/2013: v0.99 - hot-tested display + target temperature setting.
  12. //4/09/2013: v1.00 - fixed sensor temperature overflow issue. First operational release.
  13. //4/14/2013: v1.10 - added gain control - now it supports Fakkos.


  14. #include <htc.h>
  15. #include <string.h>                                        //we use strcpy
  16. #include "config.h"                                        //internal rc oscillator, no clock out
  17. #include "gpio.h"
  18. #include "delay.h"
  19. #include "adc.h"
  20. //#include "lcd_4bit.h"                                //we use lcd4bit
  21. //#include "misc.h"                                        //we use ultoa

  22. //for compatability
  23. #define PORTA                        GPIO
  24. #define TRISA                        TRISIO

  25. //hardware configuration
  26. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  27. #define HEATER_DDR                TRISA
  28. #define HEATER                        (1<<1)                //heater Positive - active high

  29. #define SENSOR_PORT                PORTA                //temperature sensor
  30. #define SENSOR_DDR                TRISA
  31. #define SENSOR                        (1<<4)                //temperature sensor on pa4
  32. #define SENSOR_ADC                ADC_AN3                //pa.4 = an3
  33. #define Vref                        5000ul                //reference voltage for the adc
  34. #define Rm                                1200                //in ohm * 10. Measurement resistor in series with the ptc sensor in the heater
  35. //ptc resistance: 50ohm at room temperature and goes to 120ohm at 400c, fairly linear.
  36. //connection: Vref/Vcc -> Rm -> adc -> PTC -> GND
  37. #define Temp_Low                25                        //low temp
  38. #define dOhm_at_Low                500                        //ptc resistance (in ohm) at Temp_Low
  39. #define Temp_High                400                        //high temp
  40. #define dOhm_at_High        1200                //ptc resistance (in ohm) at Temp_High
  41. //for fake hakko handles (fakkos)
  42. //#define dOhm_at_High        1700                //ptc resistance (in ohm) at Temp_High
  43. #define ADC2Ohm(adc)        ((unsigned long) Rm * (adc) / (1024 - (adc)))        //convert 10-bit adc to Ohm readings
  44. #define Ohm2Temp(dohm)        (((dohm)<dOhm_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(dohm) - dOhm_at_Low) * (Temp_High - Temp_Low) / (dOhm_at_High - dOhm_at_Low)))

  45. #define TARGET_PORT                PORTA                //pot to set target temperature
  46. #define TARGET_DDR                TRISA
  47. #define TARGET                        (1<<0)                //target temperature set on pa0
  48. #define TARGET_ADC                ADC_AN0                //pa.0=an0
  49. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  50. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  51. //specify led indicators
  52. //we use two leds
  53. //green led - on = target temperature has been reached
  54. //red led - on = heater on (target temperature has not been reached)
  55. #define LED_PORT                PORTA                //port for green led indicators
  56. #define LED_DDR                        TRISA
  57. #define LEDG                        (1<<2)                //green led indicator. comment out if not used
  58. #define LEDR                        (1<<5)                //red led indicator. comment out if not used

  59. #define LOOP_PR                        100                        //loop period, in ms

  60. #define LCD_DEGREEC                1                        //lcd_degree char

  61. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  62. //end hardware configuration

  63. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  64. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  65. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  66. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  67. //celsius / fahrenheit selector
  68. #define C2F_PORT                PORTA
  69. #define C2F_DDR                        TRISA
  70. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  71. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  72. //global variables
  73. unsigned char loop_cnt=0;                        //loop counter
  74. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  75. unsigned short tgt_adc, tgt=0;
  76. //unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  77. #if 0                                                                //no lcd display
  78. //for the lcd - lcd16x2
  79. unsigned char vRAM[17];                                //display ram
  80. const unsigned char str0[]="938 Ctrller v1.0";
  81. const unsigned char ver[] ="--version  1.0--";
  82. const unsigned char str1[]="TARGET=    C    ";
  83. const unsigned char str2[]="SENSOR=    C    ";
  84. const unsigned char str3[]="TGT=    /TMP=   ";

  85. const unsigned char lcd_degreeC[]={
  86.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  87. const unsigned char lcd_up[]={
  88.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  89.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  90.         };

  91. #define LCD_UP                        2                                                        //0x01 is special charter
  92. #endif
  93.        
  94. //initialize the controller
  95. void ctrl_init(void) {
  96.         HEATER_OFF(HEATER);                                        //turn off heater
  97.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  98.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  99.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  100.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  101.         IO_IN(TARGET_DDR, TARGET);                //target as input
  102.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  103.         adc_init();                                                //reset the adc module
  104.        
  105.         //load up lcd special chacterators
  106.         //lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  107.         //lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  108. }

  109. //read solder sensors
  110. unsigned short read_sensor(void) {
  111.         //unsigned short tmp;                                //tmp variable
  112.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  113.         return Ohm2Temp(ADC2Ohm(tmp_adc));        //lowest 6 bits
  114.         //return ADC2Ohm(tmp);
  115. }


  116. //read the pot that sets the target temperature
  117. //adc 0 -> TARGET_MIN
  118. //adc 1023 -> TARGET_MAX
  119. unsigned short read_target(void) {
  120.         //unsigned short tmp;                                //tmp variable
  121.         tgt_adc = adc_read(TARGET_ADC);                //read the pot
  122.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  123. }

  124. //reset the chip
  125. void mcu_init(void) {
  126.         //IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  127.        
  128.         ANSEL=0x00;                                                //all pins PORTA
  129.        
  130.         //ANSELH=0x00;

  131.         CMCON = 0x07;                                        //turn off analog comparators
  132.         //CM2CON0 = 0x00;

  133. }

  134. //adc the sensors
  135. void ctrl_adc(void) {
  136.         //lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  137.         //if (lcd_displayC) {        //pin is pulled high -> celsius
  138.                 tmp=read_sensor();                        //read the pot / target temperature
  139.                 tgt=read_target();                        //read temperature sensor,
  140.         //} else {                                                //pin is pulled low - fahrenheit
  141.                 //tmp=C2F(read_sensor());                        //read the pot / target temperature
  142.                 //tgt=C2F(read_target());                        //read temperature sensor,
  143.         //}
  144. }

  145. //control the heater
  146. void ctrl_heater(void) {
  147.         //temperature control logic
  148.         if (tmp < tgt) {
  149.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  150.                 HEATER_ON(HEATER);                        //turn on the heater
  151.         } else {
  152.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  153.                 HEATER_OFF(HEATER);                        //turn off the heater
  154.         }

  155. }

  156. #if 0
  157. //display - 1line format
  158. void ctrl_display1(void) {
  159.         //process line0
  160.         strcpy(vRAM, str3);
  161.         ultoa(&vRAM[4], tgt, 3);
  162.         ultoa(&vRAM[13], tmp, 3);
  163.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  164.         lcd_display(LCD_Line0, vRAM);
  165. }

  166. //display - 2line format
  167. void ctrl_display2(void) {
  168.         //process line0
  169.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  170.         if(lcd_displayC == 0) vRAM[11]='F';
  171.         ultoa(&vRAM[7], tgt, 3);
  172.         ultoa(&vRAM[12], tgt_adc, 4);
  173.         if (tgt > tmp) vRAM[6]=LCD_UP;
  174.         lcd_display(LCD_Line0, vRAM);
  175.                
  176.         //process line1
  177.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  178.         if (lcd_displayC == 0) vRAM[11]='F';
  179.         ultoa(&vRAM[7], tmp, 3);
  180.         ultoa(&vRAM[12], tmp_adc, 4);
  181.         lcd_display(LCD_Line1, vRAM);
  182.        
  183. }
  184. #endif

  185. void main(void)
  186. {
  187.         mcu_init();                                                //reset the chip
  188.         //lcd_init();                                                //reset the lcd
  189.         ctrl_init();                                        //reset the controller

  190.         //display sign-on message
  191.         //strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  192.         //strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  193.         delay_ms(1000);

  194.         while (1){
  195.                 //TODO Auto-generated main function

  196.                 //read the tempeature info
  197.                 //HEATER_OFF();                                //turn off the heater
  198.                 //read the sensors
  199.                 ctrl_adc();
  200.                
  201.                 //control the heater
  202.                 ctrl_heater();
  203.                
  204.                 //update display
  205.                 //ctrl_display1();                        //one-line display
  206.                 //ctrl_display2();                        //two-line display
  207.                
  208.                 //waste some time
  209.                 delay_ms(LOOP_PR);                //waste some time
  210.         }
  211. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-15 07:15:58 | 显示全部楼层
here is the hex file for the 12f675 controller:

  1. :100000002030840032300C208316FF2390008301BF
  2. :10001000B82904068001840A0406031D0928640027
  3. :1000200000348312B200B31B1C2833088A00320844
  4. :10003000B20A0319B30A82008313331883173208F4
  5. :08004000B20A84000008080068
  6. :10031A0083169F0107308312990008008312AD00EB
  7. :10032A008312AD032D0F9529080083169F121F16FD
  8. :10033A0083129F171F140800D800D80AD80303197C
  9. :10034A0000340310D70CD60CD50CD40CA329831275
  10. :10035A00B3225408A5005508A6001F225408A1007C
  11. :10036A005508A200080083128D21D721E830A90080
  12. :10037A000330AA00C621AC21FE216430A900AA01DB
  13. :10038A00BF29CC29C830AB00AC018312EA21831201
  14. :10039A0029080319AA03A903290A03192A0A03190E
  15. :1003AA000800C72900000000000000008312851021
  16. :1003BA0083168510DB30831285058316850505169D
  17. :1003CA000514851583129A21080083122B088312BB
  18. :1003DA0093212C08AB00AC01F429FF3093212B08A0
  19. :1003EA000319AC03AB032B0A03192C0A03190800DF
  20. :1003FA00F229831222082602031D052A2108250252
  21. :10040A000318132A851600000000000000000511D9
  22. :10041A00000000000000000085140800851200009A
  23. :10042A0000000000000005150000000000000000A8
  24. :10043A00851008000030831246225408A30055088C
  25. :10044A00A4001830D8000130D900DA01DB012408F1
  26. :10045A00D5002308D400D601D701C2230A30A1212E
  27. :10046A005408A9005508AA005608AB005708AC0062
  28. :10047A002A08D5002908D400C830D4070318D50A99
  29. :10048A0008008312B100702AC3309F0583169F01AA
  30. :10049A009F0A842A1F08C33904389F0002306C2A35
  31. :1004AA001F08C33908389F0004306C2A1F08C33953
  32. :1004BA000C389F0008306C2A1F08C33910389F0077
  33. :1004CA0010306C2A1F08C33914389F002030831655
  34. :1004DA009F00842A6F2A831231080319492A043A91
  35. :1004EA0003194F2A0C3A0319552A043A03195B2AAD
  36. :1004FA001C3A0319612A043A0319672A6F2A000071
  37. :10050A0000000000000000000000000000000000E1
  38. :10051A0000000000000000000000000000000000D1
  39. :10052A0000000000000000000000000000000000C1
  40. :10053A0000000000000000000000000000000000B1
  41. :10054A000000000083129F149F18A92A1E08D500D4
  42. :10055A00D40183161E08D404831208000C308312B7
  43. :10056A0046225408A7005508A800B030D800043025
  44. :10057A00D900DA01DB012808D5002708D400D60102
  45. :10058A00D701C223B2010430B3002708B202031C08
  46. :10059A00B3032808B3023208D8003308D900DA01B5
  47. :1005AA00DB01472300305702031DE52A00305602BB
  48. :1005BA00031DE52A01305502031DE52AF4305402D1
  49. :1005CA00031C422B0C30D400FE30D500FF30D6007D
  50. :1005DA00D7005408A9005508AA005608AB005708C6
  51. :1005EA00AC00B030D8000430D900DA01DB012808A9
  52. :1005FA00D5002708D400D601D701C223B20104309E
  53. :10060A00B3002708B202031CB3032808B302320856
  54. :10061A00D8003308D900DA01DB0147232908D407B7
  55. :10062A002A0803182A0FD5072B0803182B0FD607F9
  56. :10063A002C0803182C0AD7077730D8000130D900C4
  57. :10064A000030DA01DB01C223BC30D8000230D90005
  58. :10065A000030DA01DB0147235408AD005508AE002B
  59. :10066A005608AF005708B0002E08D5002D08D40050
  60. :10067A001930D4070318D50A452B1930D400D501EF
  61. :10068A008312080084018312B401DC01DD01DE015A
  62. :10069A00DF01580859045A045B040319572BC03068
  63. :1006AA00B405622BD401D501D601D701F02B031072
  64. :1006BA00D80DD90DDA0DDB0DB40ADB1F5C2BB40A99
  65. :1006CA000310DC0DDD0DDE0DDF0D5B085702031D87
  66. :1006DA00782B5A085602031D782B59085502031D18
  67. :1006EA00782B58085402031C8A2B5C145808D4022D
  68. :1006FA005908031C590FD5025A08031C5A0FD6026F
  69. :10070A005B08031C5B0FD7020310DB0CDA0CD90C55
  70. :10071A00D80CB40334083F39031D652B341FA22BB0
  71. :10072A000310FF30D407D409031CD507D509031CCD
  72. :10073A00D607D609031CD707D7095408D800550885
  73. :10074A00D9005608DA005708DB005C08D4005D08B7
  74. :10075A00D5005E08D6005F08D700B41FF02B03103F
  75. :10076A00FF30D407D409031CD507D509031CD607C3
  76. :10077A00D609031CD707D709F02B84015408DC00DB
  77. :10078A005508DD005608DE005708DF00D601D701FC
  78. :10079A00D401D5010310DF0CDE0CDD0CDC0C031CCC
  79. :1007AA00E42B5808D40759080318590FD5075A08D3
  80. :1007BA0003185A0FD6075B0803185B0FD7075C08A4
  81. :1007CA005D045E045F040319F02B0310D80DD90DE4
  82. :1007DA00DA0DDB0DCF2B840803190034570880008B
  83. :1007EA008403560880008403550880008403540853
  84. :0407FA008000003447
  85. :02400E00843FED
  86. :00000001FF
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-15 07:18:19 | 显示全部楼层
It worked as expected - I ran t he code on a 12v power supply but it should have no problem at a higher voltage - faster response time if anything.

This thing is so simple that you can probably put it together with your junkbox parts, :).

出0入0汤圆

发表于 2013-4-15 15:01:37 | 显示全部楼层
智能型高精度温度控制,检测点是关键...

出0入0汤圆

 楼主| 发表于 2013-4-17 07:24:57 | 显示全部楼层
Hakko / Fakko 907 handles (for Hakko 936 stations) use A1321 heaters (ptc temperature sensor). Atten 936 stations use A1322 heaters (thermocouple sensors). Generally, people use an amplifier to read off the output voltage from the thermocouple.

I just found out that the resistance on the thermocouple goes from 2ohm at room temperature to over 60ohm at pretty hot temperature. So it is entirely possible (and likely) that the software I wrote earlier can be easily modified to drive A1322 - as a matter of fact, the code to drive A1322 can be used to drive A1321, with gain reduced.

I will experiment more and report back.

出0入0汤圆

 楼主| 发表于 2013-4-21 01:01:31 | 显示全部楼层
I will experiment more and report back.


Both bad and good news.

Bad news:

the resistance of the thermocouple could only be read at very impedance -> making it impossible for a mcu's adc. I explored the possibilities of lowering the adc reference voltage to provide better resolution but in the end decided against it - not enough resolution even if out-of-spec Vref is used.

Good news:

the output voltage (around 20mv at the highest temperature) can be amplified easily and then adc'd by the mcu.

Here is what I experimented.



R1/R2/Q1/U1 form the amplifier - R6 is optional (for protection).

R3/R4 form a virtual ground.

V2 is the thermocouple. The output is picked across R2. the voltage gain is R2/R1 -> about 100x in this case. the plot shows the gain to be fairly linear.

I experimented TL082 and NE5532. Both work well (under 5v and 12v). Except that TL082 @ 5v would not output below 0.27v (100x) or 27mv (10x). NE5532 has no such issues.

You will notice that the amplifier is essentially a high-side current sense amplifier. So if you have a commercial current sense amplifier, you can use it here. Some current sense amplifiers don't work well if the input voltage is less than 20mv.

R4 can be replaced with a TL431 (with adjustments to R3) or any voltage reference.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-4-21 18:34:34 | 显示全部楼层
这个好象现在已有很成熟的产品了啊,伍德先生是想自己DIY么...?

出0入0汤圆

 楼主| 发表于 2013-4-21 20:25:35 | 显示全部楼层
for fun. I have a few handles + stations but the stations don't drive the fake ones as well, thus my desire to do my own.

Those stations are analog solutions and I am surprised that the manufacturers hadn't go to a mcu-based solution, at least for the low-end ones.

出0入0汤圆

 楼主| 发表于 2013-4-23 07:08:07 | 显示全部楼层
Here is the finished design.



V1 is the temperature sensor (a thermocouple) in the handle. Heater is the handle's heating element.

I used NE5532 as the thermocouple amplifier - the schematic used TL082 - which incidentally doesn't work in the 5v environment.

Gain control is implemented by replacing R7 with a 1k resistor + 1k pot, making gain adjustment from 50x - 100x.

Code:

  1. //code to control an atten907 /4-wire heater (thermocouple temperature sensor)
  2. //with a pot (to control temperature)
  3. //Host: 12F675. Minimalist implementation: No LCD, no C2F, ...
  4. //version history for 16F684
  5. //4/07/2013: v0.90 - initial code adapted for 16F684
  6. //code to control an atten907 938/4-wire heater
  7. //with a pot (to control temperature)
  8. //version history
  9. //4/20/2013: v0.90 - initial code integrated
  10. //4/22/2013: v1.00 - 1st hot-tested. Success!

  11. #include <htc.h>
  12. #include <string.h>                                        //we use strcpy
  13. #include "config.h"                                        //internal rc oscillator, no clock out
  14. #include "gpio.h"
  15. #include "delay.h"
  16. #include "adc.h"
  17. //#include "lcd_4bit.h"                                //we use lcd4bit
  18. //#include "misc.h"                                        //we use ultoa

  19. //for compatability for 12F675
  20. #define PORTA                        GPIO
  21. #define TRISA                        TRISIO

  22. //hardware configuration
  23. #define HEATER_PORT                PORTA                //turn on / off the heaterP/N
  24. #define HEATER_DDR                TRISA
  25. #define HEATER                        (1<<1)                //heater Positive - active high

  26. #define SENSOR_PORT                PORTA                //temperature sensor
  27. #define SENSOR_DDR                TRISA
  28. #define SENSOR                        (1<<0)                //temperature sensor on pa0
  29. #define SENSOR_ADC                ADC_AN0                //pa.0 = an0
  30. #define Vref                        5000ul                //reference voltage for the adc
  31. //thermocouple output: 0mv at 25c and 20mv at 400c
  32. //connection: thermocouple -> thermocouple amplifier -> adc
  33. //resistance curve
  34. #define Temp_Low                25                        //low temp, in celsius
  35. #define Temp_High                400                        //high temp, in celsius
  36. //a1321 sensor curve
  37. #define mv_at_Low                5                        //ptc resistance (in ohm) at Temp_Low
  38. #define mv_at_High                2000                //ptc resistance (in ohm) at Temp_High
  39. #define ADC2mv(adc)                ((unsigned long) ((adc) * Vref / 1024)        //convert 10-bit adc to Ohm readings
  40. #define mv2Temp(mv)                (((mv)<mv_at_Low)?Temp_Low:(Temp_Low + ((unsigned long)(mv) - mv_at_Low) * (Temp_High - Temp_Low) / (mv_at_High - mv_at_Low)))

  41. #define TARGET_PORT                PORTA                //pot to set target temperature
  42. #define TARGET_DDR                TRISA
  43. #define TARGET                        (1<<2)                //target temperature set on pa2
  44. #define TARGET_ADC                ADC_AN2                //pa.2=an2
  45. #define TARGET_MIN                200                        //minimum target temperature, in C (adc reading. top 6 bits
  46. #define TARGET_MAX                480                        //maximum target temperature, in C (adc reading. top 6 bits

  47. //specify led indicators
  48. //we use two leds
  49. //green led - on = target temperature has been reached
  50. //red led - on = heater on (target temperature has not been reached)
  51. #define LED_PORT                PORTA                //port for green led indicators
  52. #define LED_DDR                        TRISA
  53. #define LEDG                        (1<<4)                //green led indicator. comment out if not used
  54. #define LEDR                        (1<<5)                //red led indicator. comment out if not used

  55. #define LOOP_PR                        100                        //loop period, in ms

  56. #define LCD_DEGREEC                1                        //lcd_degree char

  57. #define ADC_MASK                0x3f                //adc mask. 6 bits        - not used
  58. //end hardware configuration

  59. #define HEATER_ON(pins)                do {NOP4(); IO_SET(HEATER_PORT, pins); } while (0)        //turn on heater. active low
  60. #define HEATER_OFF(pins)        do {NOP4(); IO_CLR(HEATER_PORT, pins); } while (0)        //turn on heater, active high

  61. #define LED_ON(pins)        IO_SET(LED_PORT, pins)                //turn on led, active low
  62. #define LED_OFF(pins)        IO_CLR(LED_PORT, pins)                //turn off led, active high

  63. //celsius / fahrenheit selector
  64. #define C2F_PORT                PORTA
  65. #define C2F_DDR                        TRISA
  66. #define C2F_PIN                        (1<<3)                //on pa3 - 0 = fahrenheit. 1 = celsius (with a pull-up)
  67. #define C2F(degree_c)        (9 * (degree_c) / 5 + 32)        //convert celsius to fahrenheit

  68. //global variables
  69. unsigned char loop_cnt=0;                        //loop counter
  70. unsigned short tmp_adc, tmp=0;                                //temperature sensor
  71. unsigned short tgt_adc, tgt=0;
  72. //unsigned char lcd_displayC;        //display in C indicator = 1 = displa in Celsius. 0=Fahrenheit

  73. #if 0                                                                //no lcd display
  74. //for the lcd - lcd16x2
  75. unsigned char vRAM[17];                                //display ram
  76. const unsigned char str0[]="938 Ctrller v1.0";
  77. const unsigned char ver[] ="--version  1.0--";
  78. const unsigned char str1[]="TARGET=    C    ";
  79. const unsigned char str2[]="SENSOR=    C    ";
  80. const unsigned char str3[]="TGT=    /TMP=   ";

  81. const unsigned char lcd_degreeC[]={
  82.         0x07, 0x05, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00};

  83. const unsigned char lcd_up[]={
  84.         //0x04, 0x0e, 0x1f, 0x04, 0x04, 0x04, 0x0a, 0x0f
  85.         0x04, 0x0e, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00
  86.         };

  87. #define LCD_UP                        2                                                        //0x01 is special charter
  88. #endif
  89.        
  90. //initialize the controller
  91. void ctrl_init(void) {
  92.         HEATER_OFF(HEATER);                                        //turn off heater
  93.         IO_OUT(HEATER_DDR, /*HEATERN | */HEATER);        //heater as output

  94.         LED_OFF(LEDG | LEDR);                        //turn off the leds
  95.         IO_OUT(LED_DDR, LEDG | LEDR);        //led as output

  96.         IO_IN(SENSOR_DDR, SENSOR);                //sensor as input
  97.         IO_IN(TARGET_DDR, TARGET);                //target as input
  98.         IO_IN(C2F_DDR, C2F_PIN);                //c2f selector as input

  99.         adc_init();                                                //reset the adc module
  100.        
  101.         //load up lcd special chacterators
  102.         //lcd_cgram(LCD_DEGREEC, lcd_degreeC);                //load up the special char
  103.         //lcd_cgram(LCD_UP, lcd_up);                //load up the special char
  104. }

  105. //read solder sensors
  106. unsigned short read_sensor(void) {
  107.         //unsigned short tmp;                                //tmp variable
  108.         tmp_adc=adc_read(SENSOR_ADC);                //read the temperature sensor
  109.         return mv2Temp(ADC2mv(tmp_adc));        //lowest 6 bits
  110.         //return ADC2Ohm(tmp);
  111. }


  112. //read the pot that sets the target temperature
  113. //adc 0 -> TARGET_MIN
  114. //adc 1023 -> TARGET_MAX
  115. unsigned short read_target(void) {
  116.         //unsigned short tmp;                                //tmp variable
  117.         //tgt_adc = adc_read(TARGET_ADC);                //read the pot, if clock-wise turns increase tgt_adc
  118.         tgt_adc = 1024-adc_read(TARGET_ADC);                //read the pot, if clock-wise turns decrease tgt_adc
  119.         return TARGET_MIN + (unsigned long) tgt_adc * (TARGET_MAX - TARGET_MIN) / 1024;                        //lowest 6 bits
  120. }

  121. //reset the chip
  122. void mcu_init(void) {
  123.         //IRCF2=1, IRCF1=1, IRCF0=0;                //running at 4Mhz
  124.        
  125.         ANSEL=0x00;                                                //all pins PORTA
  126.        
  127.         //ANSELH=0x00;

  128.         CMCON = 0x07;                                        //turn off analog comparators
  129.         //CM2CON0 = 0x00;

  130. }

  131. //adc the sensors
  132. void ctrl_adc(void) {
  133.         //lcd_displayC = IO_GET(C2F_PORT, C2F_PIN);        //read c2f_pin -> 0=celsius, 1=fehrenheit
  134.         //if (lcd_displayC) {        //pin is pulled high -> celsius
  135.                 tmp=read_sensor();                        //read the pot / target temperature
  136.                 tgt=read_target();                        //read temperature sensor,
  137.         //} else {                                                //pin is pulled low - fahrenheit
  138.                 //tmp=C2F(read_sensor());                        //read the pot / target temperature
  139.                 //tgt=C2F(read_target());                        //read temperature sensor,
  140.         //}
  141. }

  142. //control the heater
  143. void ctrl_heater(void) {
  144.         //temperature control logic
  145.         if (tmp < tgt) {
  146.                 LED_ON(LEDR); NOP4(); LED_OFF(LEDG);        //turn on the red led / off the green led
  147.                 HEATER_ON(HEATER);                        //turn on the heater
  148.         } else {
  149.                 LED_OFF(LEDR); NOP4(); LED_ON(LEDG);        //turn off the red led / on the green led
  150.                 HEATER_OFF(HEATER);                        //turn off the heater
  151.         }

  152. }

  153. #if 0
  154. //display - 1line format
  155. void ctrl_display1(void) {
  156.         //process line0
  157.         strcpy(vRAM, str3);
  158.         ultoa(&vRAM[4], tgt, 3);
  159.         ultoa(&vRAM[13], tmp, 3);
  160.         if (tgt > tmp) vRAM[7]=LCD_UP;        //insert the up char
  161.         lcd_display(LCD_Line0, vRAM);
  162. }

  163. //display - 2line format
  164. void ctrl_display2(void) {
  165.         //process line0
  166.         strcpy(vRAM, str1); vRAM[10]=LCD_DEGREEC;
  167.         if(lcd_displayC == 0) vRAM[11]='F';
  168.         ultoa(&vRAM[7], tgt, 3);
  169.         ultoa(&vRAM[12], tgt_adc, 4);
  170.         if (tgt > tmp) vRAM[6]=LCD_UP;
  171.         lcd_display(LCD_Line0, vRAM);
  172.                
  173.         //process line1
  174.         strcpy(vRAM, str2); vRAM[10]=LCD_DEGREEC;
  175.         if (lcd_displayC == 0) vRAM[11]='F';
  176.         ultoa(&vRAM[7], tmp, 3);
  177.         ultoa(&vRAM[12], tmp_adc, 4);
  178.         lcd_display(LCD_Line1, vRAM);
  179.        
  180. }
  181. #endif

  182. void main(void)
  183. {
  184.         mcu_init();                                                //reset the chip
  185.         //lcd_init();                                                //reset the lcd
  186.         ctrl_init();                                        //reset the controller

  187.         //display sign-on message
  188.         //strcpy(vRAM, str0); lcd_display(LCD_Line0, vRAM);
  189.         //strcpy(vRAM, ver ); lcd_display(LCD_Line1, vRAM);
  190.         delay_ms(1000);

  191.         while (1){
  192.                 //TODO Auto-generated main function

  193.                 //read the tempeature info
  194.                 //HEATER_OFF();                                //turn off the heater
  195.                 //read the sensors
  196.                 ctrl_adc();
  197.                
  198.                 //control the heater
  199.                 ctrl_heater();
  200.                
  201.                 //update display
  202.                 //ctrl_display1();                        //one-line display
  203.                 //ctrl_display2();                        //two-line display
  204.                
  205.                 //waste some time
  206.                 delay_ms(LOOP_PR);                //waste some time
  207.         }
  208. }
复制代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

 楼主| 发表于 2013-4-23 07:08:49 | 显示全部楼层
Hex file if you just wanted to burn it:
  1. :100000002030840032300C208316FF2390008301BF
  2. :10001000D62904068001840A0406031D0928640009
  3. :020020000034AA
  4. :1003520083169F0107308312990008008312AD00B3
  5. :100362008312AD032D0FB129080083161F139F12AC
  6. :100372001F1683129F171F131F140800D800D80AD4
  7. :10038200D803031900340310D70CD60CD50CD40CA7
  8. :10039200C1298312D0225408A5005508A6003D2287
  9. :1003A2005408A1005508A20008008312A921F521D2
  10. :1003B200E830A9000330AA00E421CA211C226430DB
  11. :1003C200A900AA01DD29EA29C830AB00AC018312D9
  12. :1003D2000822831229080319AA03A903290A031967
  13. :1003E2002A0A03190800E5290000000000000000A5
  14. :1003F2008312851083168510CF30831285058316EC
  15. :1004020085050514051585158312B621080083128A
  16. :100412002B088312AF212C08AB00AC01122AFF304B
  17. :10042200AF212B080319AC03AB032B0A03192C0AC7
  18. :1004320003190800102A831222082602031D232A08
  19. :10044200210825020318312A851600000000000049
  20. :1004520000000512000000000000000085140800E2
  21. :1004620085120000000000000000051600000000D8
  22. :100472000000000085100800083083126B22D601AC
  23. :100482000430D70054085602A3005508031C550A2D
  24. :100492005702A4001830D8000130D900DA01DB017C
  25. :1004A2002408D5002308D400D601D701C2230A307C
  26. :1004B200BF215408A9005508AA005608AB005708E6
  27. :1004C200AC002A08D5002908D400C830D407031884
  28. :1004D200D50A08008312B1008C2A9F111F118316BE
  29. :1004E2001F08F0390138892A9F111F1583161F082A
  30. :1004F200F0390238892A9F151F1183161F08F03917
  31. :100502000438892A9F151F1583161F08F0390838E9
  32. :100512009F009A2A8B2A8312310803196E2A043A01
  33. :100522000319752A0C3A03197C2A043A0319832AFF
  34. :100532008B2A000000000000000000000000000004
  35. :1005420000000000000000000000000000000000A9
  36. :100552000000000000000000000000000000000099
  37. :100562000000000000000000000000000000000089
  38. :100572000000000000000000000000000000000079
  39. :1005820000000000000083129F149F18C62A1E0854
  40. :10059200D500D40183161E08D4048312080000304B
  41. :1005A20083126B225408A7005508A8008830D8008F
  42. :1005B2001330D900DA01DB012808D5002708D4005E
  43. :1005C200D601D701C2230A30BF2100305702031DD2
  44. :1005D200F42A00305602031DF42A00305502031D8E
  45. :1005E200F42A05305402031C422BFB30D400FF30A6
  46. :1005F200D500D600D7005408A9005508AA0056080D
  47. :10060200AB005708AC008830D8001330D900DA01AB
  48. :10061200DB012808D5002708D400D601D701C22360
  49. :100622000A30BF212908D4072A0803182A0FD50740
  50. :100632002B0803182B0FD6072C0803182C0AD707F0
  51. :100642007730D8000130D9000030DA01DB01C22353
  52. :10065200CB30D8000730D9000030DA01DB01472364
  53. :100662005408AD005508AE005608AF005708B00058
  54. :100672002E08D5002D08D4001930D4070318D50A46
  55. :10068200452B1930D400D50183120800840183124E
  56. :10069200B201DC01DD01DE01DF01580859045A0410
  57. :1006A2005B040319572BC030B205622BD401D5016C
  58. :1006B200D601D701F02B0310D80DD90DDA0DDB0DC1
  59. :1006C200B20ADB1F5C2BB20A0310DC0DDD0DDE0D5E
  60. :1006D200DF0D5B085702031D782B5A085602031DD3
  61. :1006E200782B59085502031D782B58085402031C15
  62. :1006F2008A2B5C145808D4025908031C590FD502DE
  63. :100702005A08031C5A0FD6025B08031C5B0FD70260
  64. :100712000310DB0CDA0CD90CD80CB20332083F39C7
  65. :10072200031D652B321FA22B0310FF30D407D409FF
  66. :10073200031CD507D509031CD607D609031CD70706
  67. :10074200D7095408D8005508D9005608DA005708C6
  68. :10075200DB005C08D4005D08D5005E08D6005F08A7
  69. :10076200D700B21FF02B0310FF30D407D409031CAB
  70. :10077200D507D509031CD607D609031CD707D70905
  71. :10078200F02B84015408DC005508DD005608DE0019
  72. :100792005708DF00D601D701D401D5010310DF0CC1
  73. :1007A200DE0CDD0CDC0C031CE42B5808D4075908C2
  74. :1007B2000318590FD5075A0803185A0FD6075B08B2
  75. :1007C20003185B0FD7075C085D045E045F0403191E
  76. :1007D200F02B0310D80DD90DDA0DDB0DCF2B8408C9
  77. :1007E20003190034570880008403560880008403EC
  78. :0C07F20055088000840354088000003487
  79. :02400E00843FED
  80. :00000001FF
复制代码

出0入0汤圆

 楼主| 发表于 2013-4-23 07:12:43 | 显示全部楼层
A quick note about this particular line:

  1. unsigned short read_target(void) {
  2.         //unsigned short tmp;                                //tmp variable
  3.         //tgt_adc = adc_read(TARGET_ADC);                //read the pot, if clock-wise turns increase tgt_adc
  4.         tgt_adc = 1024-adc_read(TARGET_ADC);                //read the pot, if clock-wise turns decrease tgt_adc
复制代码
I wired my pot (RV1) incorrectly so that when I turn the pot clockwise, my adc reading go down, rather than go up. So the solution is to invert the reading.

If you wise the pot correctly, you don't need to do this.

The whole thing is implemented onto a perf board the size of a credit card and vecro'd to a HP laptop power supply.

Total cost: less than $5 - the 5-pin connector is the most expensive part.

出0入0汤圆

发表于 2013-4-23 12:25:59 | 显示全部楼层
millwood0 发表于 2013-4-21 20:25
for fun. I have a few handles + stations but the stations don't drive the fake ones as well, thus my ...

很佩服您的精力和技术...

出0入0汤圆

 楼主| 发表于 2013-4-24 06:19:53 | 显示全部楼层
It is all about having fun, :)

I don't have a T12 handle. But I am thinking about rewriting my code to drive a T12-like handle, by rewiring a thermocouple-based heater - putting the thermocouple in serial with the heater.

出0入0汤圆

发表于 2013-4-24 07:22:55 | 显示全部楼层
thanks for sharing mate!

出0入0汤圆

 楼主| 发表于 2013-4-24 08:30:19 | 显示全部楼层
Here is the hardware set-up for a T12-driver:



The only change is to uncomment this line:

  1.                 HEATER_OFF(HEATER);                                //turn off the heater
复制代码
The way the T12 tip works is to turn off the power to it when you adc the thermocouple.

I have not built this version so try it at your own risk.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-4-29 14:00:22 | 显示全部楼层
millwood0 发表于 2013-4-24 06:19
It is all about having fun, :)

I don't have a T12 handle. But I am thinking about rewriting my code ...

T12手柄得支持,这个社会拥有量也非常大,手柄也好买。另外问下上图的NE5532能用LM358之类的运放代替吗?

出0入0汤圆

发表于 2013-4-29 14:03:15 | 显示全部楼层
millwood0 发表于 2013-4-24 08:30
Here is the hardware set-up for a T12-driver:

I planning to port your code to stm8s103f3p6 + segament lcd :)

出0入0汤圆

 楼主| 发表于 2013-4-30 19:31:37 | 显示全部楼层
T12手柄得支持,这个社会拥有量也非常大,手柄也好买。


I never understood T12's popularity: the tips are more expensive, more fragile, and the handles are tougher to find, not to mention the 8-pin connectors.

另外问下上图的NE5532能用LM358之类的运放代替吗?


For the T12 driver? You may have to try but it should - it uses a pnp input stage, as I recall.

I planning to port your code to stm8s103f3p6 + segament lcd :)


Adding a segment lcd display is easy: you can do it via a timer isr. You just need to have a lot of pins.

Running it on a 3.3v mcu requires the use of a dedicated driver or logic level mosfets.

出0入0汤圆

 楼主| 发表于 2013-5-1 04:35:24 | 显示全部楼层
a Big challenge here is to read off a small output signal from the thermocouple. There are a few ways to do it, each with their own downsides:

1) single-rail opamp + onboard adc: this is the simplest solution. The difficult to is to find an opamp that takes rail-to-rail input and produces an output near its negative rail (ground in this case). You will find that it is not that easy to find such an opamp;
2) dual-rail opamp + onboard adc: this don't require any special opamp. However, you have to create a negative rail.
3) dedicated thermocouple amplifier: Maxim has a few that outputs digital readouts. max31855 is one such chip but some people have issues with it.

I personally find it hard to understand a T12-based solution so I tend to stay away from it.

出0入0汤圆

 楼主| 发表于 2013-5-5 07:17:01 来自手机 | 显示全部楼层
I wanted to report back about those controllers and if there is a need for pid here: I measured the tip temperature via a thermometer + its own thermocouple - placed on the tip. The temperature reading on the tip goes up or done by 1 degrees until 400c. After that it fluctuates about 2 degrees.

Based on that, I suppose pid temperature control is overkill.

出0入0汤圆

发表于 2013-12-19 15:12:51 | 显示全部楼层
millwood0 发表于 2013-4-15 02:54
I finished building a version of the hakko controller on 16F684 + LCD.

Great success and the unit i ...

我拆开手头的山寨907手柄只有两根线,而伍德先生图上的907却是4线的,这可如何是好?
不懂得电路上应该如何连接了。。。
我简单测试了下:室温下它的电阻是10Ohm左右,加热到280度时电阻变成39.7Ohm左右

出0入0汤圆

发表于 2013-12-19 15:47:50 | 显示全部楼层
sanger 发表于 2013-12-19 15:12
我拆开手头的山寨907手柄只有两根线,而伍德先生图上的907却是4线的,这可如何是好?
不懂得电路上应该如 ...

两线是热电偶的,4线的热电阻的

出0入0汤圆

发表于 2013-12-19 15:49:41 | 显示全部楼层
突然想到了yacc

出0入0汤圆

发表于 2013-12-19 15:52:10 | 显示全部楼层
这个是amobbs的英文版吗》全是蚂蚁文

出0入0汤圆

发表于 2013-12-19 16:24:22 | 显示全部楼层
HELLOWORLD_2012 发表于 2013-12-19 15:47
两线是热电偶的,4线的热电阻的

但907手柄不是热电阻的吗,而且我对铬铁头加热确实阻值会变化

出0入0汤圆

发表于 2013-12-19 16:35:54 | 显示全部楼层
sanger 发表于 2013-12-19 16:24
但907手柄不是热电阻的吗,而且我对铬铁头加热确实阻值会变化

呵呵,中国市场有三种907手柄,外观是一样的,两种4线的,一种两线的

你用mV档测下电压,手柄上有电压就是热电偶的,很容易识别,电阻也会变,但是不是用电阻来测温的

出0入0汤圆

发表于 2013-12-19 16:50:42 | 显示全部楼层
HELLOWORLD_2012 发表于 2013-12-19 16:35
呵呵,中国市场有三种907手柄,外观是一样的,两种4线的,一种两线的

你用mV档测下电压,手柄上有电压就 ...

测了下确实有数mV的电压输出,兄台对手柄这么了解,莫非是业内人士

出0入0汤圆

发表于 2013-12-19 17:12:08 | 显示全部楼层
sanger 发表于 2013-12-19 16:50
测了下确实有数mV的电压输出,兄台对手柄这么了解,莫非是业内人士

业余玩一下,不是流行白菜白光吗? 就跟风搞了一下

现在在搞高频烙铁,STM32+AD9850,全桥软谐振,频率自追踪,还在做实验

出0入0汤圆

发表于 2013-12-20 22:08:49 | 显示全部楼层
回复一下,方便查找,顺便自己做一个
顺便问一个问题,我大概翻找了下程序,居然没有找到你对adc采样得到的电压转换为相应温度的计算方法,莫非是我没有看见么

出0入0汤圆

发表于 2014-8-7 07:44:47 | 显示全部楼层
mark it. I like T12, I want do it .
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-27 15:27

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表