แฟ้มประวัติHERMANรูปถ่ายบล็อกรายการเพิ่มเติม เครื่องมือ วิธีใช้

บล็อก


13 กุมภาพันธ์

Testing times - PC to picaxe comms

I've been inspired to get my teeth into picaxe coding again and so it was time to further develop the HERMAN code. One thing that I wanted to clean up was the duty cycle timing for the kettle power - the cycle time was way too long. I had the interrupt timer operating at 1 second for clock purposes, so to speed up the kettle duty cycle the interrupt now happens more frequently to update kettle duty each minor tick. A major tick still occurs every second, triggering all other timed functions, including one-wire timing.

Once that was sorted, it was time to tackle PC to picaxe communications via the serial port. I've had picaxe to PC working for ages, but when I first tested the other direction I was perplexed at the lack of response from the picaxe. While working on the duty cycle function, I found a logic error that prevented the receive code from ever working.  smile_embaressed

OK, so now the motivation to step forwards again. Things were not straight-forward, however. The first symptom was that data was received but the picaxe never recognised the header, so always timed out. It turned out that incoming data was mostly corrupted, through timing problems. This was eventually sorted using the calibfreq command. The manual says this command should be used with caution. Of course I forgot to read that bit ... and ended up with a picaxe I could not program for quite a while. A hard reset on the power side eventually fixed it! smile_sad

In hindsight it seems blindingly obvious that I could have implemented the calibfreq for the received comms code only. I now have this working reliably.

With a header now recognised and information getting through, I ran into more problems. Most of the information sent came through ok, but it always seemed the last byte was corrupt. I still have no idea why, but I ended up shortening the data packet and sending a dummy end and now it all works.

There is more work to do to make things more robust. I intend to implement both send and receive checksums, but for now I'm happy to finally have remote control capacity for the machine.

05 กุมภาพันธ์

Better the micro you know ...

Until a few days ago the display part of my picaxe code on the brewing machine was a mess. It had been ages since I'd coded any revisions and the display only had rudimentary information on screen. For the last three months I'd needed to plug in the laptop just to see something intelligible from the 28X1 chip.

Recently I bought an Arduino and I've been catching a few minutes here and there to learn about its capabilities. There is a lot more power in this new (to me) micro. Because of this I'd neglected further picaxe development.

A couple of things changed that. A significant revision to the Picaxe Programming Editor has meant that complex code is much easier to navigate around, and that variables are much easier to keep track of - an important thing when they are in limited supply.

So while I was looking at the new Editor, I discovered that I'd done some significant recoding for the picaxe in early November that I'd forgotten about. It never got uploaded and tested ...

So all of a sudden there were display improvements and an easier way to keep track of updates ... and I'm inspired again by the micro I know.

I've posted the current HERMAN code here. There are improvements to make, but generally I'm happy with progress. I intend to add in features like:

  • start delay - allows things to be set to turn on in the early hours of the morning for a pre-heat.
  • screens to allow easy entry of mash targets and times
  • boil timer and hop addition settings
  • better implementation of variable power on the kettle - ie. shorten the duty cycle and put it in the main program loop.

On the hardware side I've been impressed with the 'shield' idea on the Arduino. Essentially a shield is a board that can piggyback onto the base Arduino board. The connectors extend all pins, power, reset and the like. Shields can be stacked on top of each other to further extend functions. As an example, I have an internet board for my Arduino (not that I've done any experiments with it yet).

I'm not sure I will implement 'shields' in the HERMAN project although the idea of beginning small and building up is appealing. Some possible 'shields' for the HERMAN project:

  • a base board with picaxe 28x1, serial programming connector, external power connector, crystal socket, reset button, power, reset and pins available on connectors.
  • an input board with facilities for DS18B20 sensors and analog inputs (ie. level sensors).
  • an ssr output driver board
08 ตุลาคม

Picaxe coding school - Part 1

I've reached a critical coding point using a picaxe 28x1 - I've run out of variables. Confused

192_9218

Doing small programs on a picaxe is easy, thanks to a simple but powerful basic interpreter. Because of its structure, it has a limited number of byte and word variables available. Once these have all been used, coding gets increasingly difficult. I find that good coding strategies are needed to stop me going crazy. Crying

Once you run out of variables, you need to find a way to re-use them without corrupting data from one routine to another. Data can be stored in random access memory (RAM) addresses or EEPROM addresses to free up variable for re-use. The problem comes in the detail, and carefully working out which variables are needed where in a program, and then making sure values are stored elsewhere before moving on.

I'm taking a break from coding to do this blog to prevent myself from going crazy at this point. I've realised that adopting some of the strategies outlined below might help me sleep tonight ;-)

Rule 1:

If a piece of code is repeated, always write a subroutine to do it.

Rule 2:

Try to minimise the depth of subroutine calls. It can be hard to keep track of which routine calls another, which makes it difficult to keep variables isolated.

One strategy is to set 'flags' to indicate a subroutine call if there needs to be a shift in call order.

Rule 3:

Make each procedure or subroutine a sealed unit - that is peek (get from RAM) all variable values at the start of the routine, and poke (store in RAM) them all at the end, freeing all variables up for other routines. If there needs to be any global variables, make sure there are good reasons for them.

Rule 4:

Start afresh with a clean slate and slowly re-build the complexity, rather than try to re-build an already complex piece of work.

The result:

After a couple of solid days of re-coding, I am still at a lesser-functioning piece of code. What I do have, though, is a much cleaner, and easily expandable piece of work. It is painful to go through the process, but if done properly will be worth it because the code will be much easier to maintain. Smile

04 มิถุนายน

Gate Valve Actuator Board

With the release of the Picaxe 14M I've been re-designing and hopefully finalising the control and driver boards for actuating the gate valves in HERMAN.
 
The designs will need to be tested on a prototype board but are probably close to a final build. The control board accepts either bush button controls or remote computer commands to open and close the gate. A multiturn potentiometer will provide position feedback. A pulse width modulated output will enable variable speed control of the motor. This means that the motor will have the capcity to slow down when close to target in the same manner as a servo motor.
 
The motor driver board has been separated from the control board for ease of servicing in case of driver failure. The board is designed to piggyback on the control board via a molex connector.
 
We now have polymorph, so this afternoon we should be close to completing the coupling between gate valve and the drive motor.
 
The schematics for the control and driver board are below (apologies for the low resolution - that is a function of the blog space upload):
 
17 พฤษภาคม

PID bug corrected

I went back through the PID coding on the picaxe tonight to try and replicate the bug that caused the heat chamber to apply 100% power when it was already too hot!
 
As suspected, the problem lies with picaxe integer maths dealing with negative numbers by simply scrolling back to maximum values. So if a byte is capable of 0-255, a simple subtraction like 5-6 does not equal minus 1, but 255. I had been using the MAX and MIN commands to limit these calculations, but they must work differently to what I had imagined.
 
My code:
Total = P - I MIN 0
 
where P=0
and I=5 (ie. -5)
does not result in Total = 0 as I had thought. I have modified the code to eliminate the MIN 0 command in this instance.
On the simulator it seems ok, so a real world test ought to work. I had not picked up the problem with the water test because the temperature in the chamber was too stable - it did not get high ever. When working with a poor recirculating rate, it is much easier to jump the temperature a little high - and when this happened it just kept going.
 
I am interstate all next week, so we won't get to brew for a while.
 
10 พฤษภาคม

PID operational

In recent spare moments I've been playing around adding the differential component to my picaxe controlled heat chamber. The PI control yielded excellent results in the mash tun, but the heat chamber did a slow oscillation above and below the target temperature (+- 0.4 deg C). By adding differential control, the swing through the target temperature is halted by adding or subtracting power depending on the rate of change.
 
The code is shown at the end of this post. It is essentially the same as the PI code from the previous post although there are some tweaks, such as using MAX and MIN limits. The differential code required some extra work because there were not enough native variables to complete the work without peeking and poking. I am sure that the code could be optimised considerably, but at this point I've concentrated on it being functional.
 
The net result is that the heat chamber, once stabilised, remains spot on target for most of its time, and only varies +- 0.1 degree. This result could be improved if an extra digit was added to calculations.
 
We will brew this coming Monday, so test out the system with grains rather than just recirculating water.
 

 
;# picaxe 40x
;# terminal 4800
'****************************************
'*            *
'*  HERMAN 6 serial controller     *
'* Craft-Brewing machine  *
'*            *
'* using PICAXE 40X     *
'*  by Arnie Wierenga   *
'*          *
'*  Version  070510   *
'*      *
'****************************************
; Test board for R&D towards HERMAN 6 control equipment
; 070509-10  - added derivate
;   - added MAX and MIN into PID calculations
init:
 symbol RXD=0 ;receive data line
 symbol MASt=1 ;DS18B20 mash tun temperature
 symbol HCt=5 ;DS18B20 heat chamber temperature
 symbol sp_dn=pin7 ;heat chamber set point down
 symbol sp_up=pin0 ;heat chamber set point up: portA pin0
 symbol hcSSR=0 ;heat chamber SSR control
 
 symbol st_spHC_msb=$50 ;stored setpoint for heat chamber - most significan byte
 symbol st_spHC_lsb=$51 ;stored setpoint for heat chamber - least significan byte
 symbol st_MASt_msb=$52 ;stored mash tun temperature - most significan byte
 symbol st_MASt_lsb=$53 ;stored mash tun temperature - least significan byte
 symbol st_HCt_msb=$54 ;stored heat chamber temperature - most significan byte
 symbol st_HCt_lsb=$55 ;stored heat chamber temperature - least significan byteb
 ;w0 = b1 : b0
 ;w1 = b3 : b2
 ;w2 = b5 : b4
 ;w3 = b7 : b6
 ;w4 = b9 : b8
 ;w5 = b11 : b10
 ;w6 = b13 : b12
 
 symbol wTraw=w0 ;raw temperature data from DS18B20
 symbol act_T=w0 ;actual temperature in * 10 degrees
 symbol aT_msb=b1
 symbol aT_lsb=b0
 symbol P=w0  ;proportional power component
 symbol spHC=w6 ;Heat chamber setpoint
 symbol sp_msb= b13
 symbol sp_lsb= b12
 symbol dT=w1 ;temperature difference set-acutal
 symbol prevT=w6 ;last temperature read retrieved from memory
 symbol pT_msb=b13
 symbol pT_lsb=b12
 symbol HCmode=b4 ;heat chamber mode: 0=off; 1=on
 symbol kP=b5 ;proportional gain
 symbol kI=b6 ;integral increment
 symbol I=b7  ;integral power component
 symbol iHC_ON=b9 ;percentage of power to apply to heat chamber
 symbol normI=b10 ;absolute value of I
 symbol iHC_OFF=b10 ;percentage of off time for heat chamber
 symbol kD=b11 ;derivative gain
 symbol D=b12 ;derivative power component
 
 symbol lastT_msb=$50 ;address for last temperature msb
 symbol lastT_lsb=$51 ;address for last temperature lsb
 symbol hcSP_msb=$52 ;address for heat chamber set point msb
 symbol hcSP_lsb=$53 ;address for heat chamber set point lsb
 symbol thisT_msb=$54 ;address for current temperature msb
 symbol thisT_lsb=$55 ;address for current temperature lsb
 
 kP=17   ;1 degree difference * % in power
 kI=1   ;2% increase in power if low; decrease if high
 spHC=670 ;670  ;starting setpoint 67.0 degrees C
 I=100   ;100 is the non-bias value
    ;<100 means decrease power
    ;>100 means increase power
 kD=60
 HCmode=0
main:
checksetpoint:
 'check to see if HC should be turned off
 if porta sp_up=1 and sp_dn=1 then
  'both buttons pressed - turn HC off
  HCmode=0
  pause 500 ;allow delay to prevent change in setpoint
 endif
 'check temperature setpoint buttons 
 if porta sp_up=1 then
  'heat chamber setpoint increase
  inc spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 500
  goto rapidsetpoint 'allow a rapid fire increase
 elseif sp_dn=1 then
  'heat chamber setpoint decrease
  dec spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 500
  goto rapidsetpoint 'allow a rapid fire increase
 endif 
 goto SSRcycle
 
rapidsetpoint:
 if porta sp_up=1 then
  'heat chamber setpoint increase
  inc spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 50
  goto rapidsetpoint 'allow a rapid fire increase
 elseif sp_dn=1 then
  'heat chamber setpoint decrease
  dec spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 50
  goto rapidsetpoint 'allow a rapid fire increase
 endif 
 
SSRcycle:
 'evaluate SSR
 if iHC_ON>0 then
  'decrement counter
  dec iHC_ON
  if HCmode>0 then
   'power on SSR for this cycle
   high hcSSR
  else
   low hcSSR
  endif
 elseif iHC_OFF>0 then
  'decrement counter
  dec iHC_OFF
  low hcSSR
 else
  'end of full duty cycle
  'read fresh data and load new duty cycle
  goto ReadTemps
 endif
 
 pause 20 ;time for one count in duty cycle
 goto main ;continue cycle until finished
 
ReadTemps:
 'read system temperatures
 ReadTemp12 MASt,wTraw ;12 bit resolution read of mash DS18B20 probe
 ;temp = raw * 0.0625
 ;to display temp in 1 decimal place * 10 (ie. integer):
 ;temp = raw * 0.625
 ;temp = raw * 5/8
 act_T= wTraw * 5/8 ;raw temp now in *10 format
   SerTxD ("Mash Temp: ", #act_T, 13, 10 ) ;serial send of mash temp to PC
 ReadTemp12 HCt,wTraw ;read Heat chamber probe
 act_T= wTraw * 5/8 ;raw temp now in *10 format
 act_T= act_T + 55  ;calibrate for mash in
   SerTxD ("Heat Chamber Temp: ", #act_T, 13, 10 ) ;send heat chamber temperature
 'store current temperature into memory for next D calculation
 poke thisT_msb, aT_msb 'store msb
 poke thisT_lsb, aT_lsb 'store lsb
 SerTxD ("Heat Chamber Targ: ", #spHC, 13, 10 ) ;send heat chamber set point
calcPID:
 'calculate heat chamber power setting [Proportional + Integral + Differential]
 if HCmode=0 then
  'heat chamber is off, no need to calculate PID
  iHC_OFF=100 ;refresh cycle values
  goto main ;return
 else
  'calculate PID and set power level (every 10 seconds)
  
  'check temperature range
  if act_T > spHC then
   'the chamber liquor it too hot
   dT=act_T-spHC
   if dT>8 then
    'we will not calculate differential - outside power band
    HCmode=2 'indicate with flag
      ;SerTxD ("outside D band", 13, 10 )
   endif
   'set P to 0%
   P=0  ;power level is determined by integral
   'and decrement I
   I=I - kI MIN 5
   SerTxD ("Decreasing I: ", #I , 13, 10 ) ;send heat chamber temperature
  else
   'the chamber liquor is too cool or ok  
   dT=spHC-act_T MAX 1000  ;delta Temp - difference between set and actual
   if dT>8 then
    'we will not calculate differential - outside power band
    HCmode=2 'indicate with flag
      ;SerTxD ("outside D band", 13, 10 )
   endif   
     SerTxD ("delta Temp: ", #dT, 13, 10 ) ;send heat chamber temperature
   P=kP * dT MAX 1000   ;Proportional component
   P=P/10   ;normalise to % power
   if P < 100 then
    'we adjust integral
    if dT=0 then
     'keep things steady
     SerTxD ("Steady I: ", #I , 13, 10 ) ;send heat chamber temperature
    else
     I=I + kI MAX 195  ;Integral component
     SerTxD ("Increasing I: ", #I , 13, 10 ) ;send heat chamber temperature
    endif
   endif
  endif
     
  SerTxD ("P: ", #P , 13, 10 ) ;send heat chamber temperature
  
  if I>100 then
   'I is adding power
   normI=I-100
   iHC_ON= P + normI MAX 100 ;Proportional + integral
  else
   'I is decreasing power
   normI=100-I
   iHC_ON= P - normI MIN 0
  endif
  'evaluate Differential
  
  'temporarilay store heat chamber set point so we can use its variable
  poke hcSP_msb, sp_msb 'store msb
  poke hcSP_lsb, sp_lsb 'store lsb
  
  'retrieve last/previous temperature
  peek lastT_msb, pT_msb 'get msb
  peek lastT_lsb, pT_lsb 'get lsb
  
  'retrieve current temperature
  peek thisT_msb, aT_msb 'get msb
  peek thisT_lsb, aT_lsb 'get lsb
  'store current temperature into memory for next D calculation
  poke lastT_msb, aT_msb 'store msb
  poke lastT_lsb, aT_lsb 'store lsb
  
  SerTxD ("Previous Temperature: ", #prevT , 13, 10 )
  'check direction of temperature change
  if prevT < act_T then
   'temperature is rising
   'calculate dT (actual - previous)
   dT=act_t-prevT
   'check we are within the powerband for D
   'differential is only added or subtracted
   'when we are within 3 degrees of target
   if HCmode=1 then
    'we calculate our D component
    D=dT * kD/10
    SerTxD ("Subtracting D: ", #D , 13, 10 )
   else
    D=0 'no D component
    SerTxD ("Outside band - D: ", #D , 13, 10 )
    HCmode=1
   endif
   
   'now subtract D to slow down the heating process
   if D>iHC_ON then
    iHC_ON=0
   else
    iHC_ON=iHC_ON-D
   endif
   SerTxD ("Result P+I-D: ", #iHC_ON , 13, 10 )
   ;I=I-D MIN 5
  else
   'temperature is falling or stable
   'calculate dT (previous - actual)
   dT=prevT-act_t
   'check we are within the powerband for D
   'differential is only added or subtracted
   'when we are within 3 degrees of target
   if HCmode=1 then
    'we calculate our D component
    D=dT * kD/10
    SerTxD ("Adding D: ", #D , 13, 10 )
   else
    D=0 'no D component
    SerTxD ("Outside band - D: ", #D , 13, 10 )
    HCmode=1
   endif
   
   'now add D to slow down the cooling process
   iHC_ON=iHC_ON+D MAX 100   
   SerTxD ("Result P+I+D: ", #iHC_ON , 13, 10 )
   ;I=I+D MAX 195
  endif
  
  'now we restore the heat chamber set point variable
  peek hcSP_msb, sp_msb 'get msb
  peek hcSP_lsb, sp_lsb 'get lsb
  
 endif
SerTxD ("norm I: ", #normI , 13, 10 ) ;send heat chamber temperature
SerTxD ("I: ", #I , 13, 10 ) ;send heat chamber temperature
iHC_ON=iHC_ON MAX 100
SerTxD ("PID: ", #iHC_ON , 13, 10 ) ;send heat chamber temperature
iHC_OFF=100-iHC_ON ;new duty cylce is loaded
 
goto main  
 
 
 
 
 
 
05 พฤษภาคม

Testing PI control on the heat chamber

With the power wiring in place and the old picaxe control gear jury-rigged to control the heat chamber, it was time last night to do some coding and test out the theory.
 
The code to control the heat chamber is remarkably simple, despite working with both Proportional and Integral components. At present, the heat chamber is able to regulate mash temperatures very well. The chamber temperature itself oscillates slightly around the setpoint. For example, the machine is running with water at the moment and the setpoint is 67.0 degrees C. The chamber is actually oscillating between 66.6 and 67.4 degrees. This is because there is no differential part in the power equation, so the oscillation represents the lag time between applying heat and actually seeing the heating effect on the outlet probe.
 
This oscillation is not a problem due to the thermal mass of the mash tun being much greater than the thermal mass of the heat chamber. The oscillation above averages at 67.0 which is the important part. This means that the mash temperature stays very stable at 67.0 (after taking into account other thermal losses in the system).
 
Now that I have an easy way to see what is happening with the heat chamber osciallation, I am inclined to add some differential to the equation, just for the sake of completing the task fully. I may wait for 'a rainy day' for this.
 
The picaxe code below includes measurement of mash tun temperature. The temperatures, set point, proportional and integral components and other information are sent via sertxd which means the picaxe terminal program can be used to monitor what is happening.
 
Picaxe Code:

 '****************************************
'*            *
'*  HERMAN 6 serial controller     *
'* Craft-Brewing machine  *
'*            *
'* using PICAXE 40X     *
'*  by Arnie Wierenga   *
'* arniew@tpg.com.au   *
'*  Version  070505   *
'*      *
'****************************************
; Test board for R&D towards HERMAN 6 control equipment
init:
 symbol RXD=0 ;receive data line
 symbol MASt=1 ;DS18B20 mash tun temperature
 symbol HCt=5 ;DS18B20 heat chamber temperature
 symbol sp_dn=pin7 ;heat chamber set point down
 symbol sp_up=pin0 ;heat chamber set point up: portA pin0
 symbol hcSSR=0 ;heat chamber SSR control
 
 symbol st_spHC_msb=$50 ;stored setpoint for heat chamber - most significan byte
 symbol st_spHC_lsb=$51 ;stored setpoint for heat chamber - least significan byte
 symbol st_MASt_msb=$52 ;stored mash tun temperature - most significan byte
 symbol st_MASt_lsb=$53 ;stored mash tun temperature - least significan byte
 symbol st_HCt_msb=$54 ;stored heat chamber temperature - most significan byte
 symbol st_HCt_lsb=$55 ;stored heat chamber temperature - least significan byteb
 ;w0 = b1 : b0
 ;w1 = b3 : b2
 ;w2 = b5 : b4
 ;w3 = b7 : b6
 ;w4 = b9 : b8
 ;w5 = b11 : b10
 ;w6 = b13 : b12
 
 symbol wTraw=w0 ;raw temperature data from DS18B20
 symbol act_T=w0 ;actual temperature in * 10 degrees
 symbol P=w0  ;proportional power component
 symbol spHC=w6 ;Heat chamber setpoint
 symbol dT=w1 ;temperature difference set-acutal
 symbol HCmode=b4 ;heat chamber mode: 0=off; 1=on
 symbol kP=b5 ;proportional gain
 symbol kI=b6 ;integral increment
 symbol I=b7  ;integral power component
 symbol iHC_ON=b9 ;percentage of power to apply to heat chamber
 symbol normI=b10 ;absolute value of I
 symbol iHC_OFF=b10 ;percentage of off time for heat chamber 
 
 kP=17   ;1 degree difference * % in power
 kI=1   ;2% increase in power if low; decrease if high
 spHC=670 ;670  ;starting setpoint 67.0 degrees C
 I=100   ;100 is the non-bias value
    ;<100 means decrease power
    ;>100 means increase power
 HCmode=0
main:
checksetpoint:
 'check to see if HC should be turned off
 if porta sp_up=1 and sp_dn=1 then
  'both buttons pressed - turn HC off
  HCmode=0
  pause 1000 ;allow delay to prevent change in setpoint
 endif
 'check temperature setpoint buttons 
 if porta sp_up=1 then
  'heat chamber setpoint increase
  inc spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 100
  goto checksetpoint 'allow a rapid fire increase
 elseif sp_dn=1 then
  'heat chamber setpoint decrease
  dec spHC
  HCmode=1 ;heat chamber is on
  iHC_ON=0 ;force a reload of cycle
  iHC_OFF=0
  pause 100
  goto checksetpoint 'allow a rapid fire increase
 endif 
 
SSRcycle:
 'evaluate SSR
 if iHC_ON>0 then
  'decrement counter
  dec iHC_ON
  if HCmode=1 then
   'power on SSR for this cycle
   high hcSSR
  else
   low hcSSR
  endif
 elseif iHC_OFF>0 then
  'decrement counter
  dec iHC_OFF
  low hcSSR
 else
  'end of full duty cycle
  'read fresh data and load new duty cycle
  goto ReadTemps
 endif
 
 pause 20 ;time for one count in duty cycle
 goto main ;continue cycle until finished
 
ReadTemps:
 'read system temperatures
 ReadTemp12 MASt,wTraw ;12 bit resolution read of mash DS18B20 probe
 ;temp = raw * 0.0625
 ;to display temp in 1 decimal place * 10 (ie. integer):
 ;temp = raw * 0.625
 ;temp = raw * 5/8
 act_T= wTraw * 5/8 ;raw temp now in *10 format
   SerTxD ("Mash Temp: ", #act_T, 13, 10 ) ;serial send of mash temp to PC
 ReadTemp12 HCt,wTraw ;read Heat chamber probe
 act_T= wTraw * 5/8 ;raw temp now in *10 format
 act_T= act_T + 55  ;calibrate for mash in
   SerTxD ("Heat Chamber Temp: ", #act_T, 13, 10 ) ;send heat chamber temperature
 SerTxD ("Heat Chamber Targ: ", #spHC, 13, 10 ) ;send heat chamber set point
calcPI:
 'calculate heat chamber power setting [Proportional + Integral]
 if HCmode=0 then
  'heat chamber is off, no need to calculate PI
  iHC_OFF=100 ;refresh cycle values
  goto main ;return
 else
  'calculate PI and set power level (every 10 seconds)
  
  'check temperature range
  if act_T > spHC then
   'the chamber liquor it too hot
   'set P to 20%
   P=0  ;power level is determined by integral
   'and decrement I
   if I>5 then
    I=I - kI
    SerTxD ("Decreasing I: ", #I , 13, 10 ) ;send heat chamber temperature
   endif
  else
   'the chamber liquor is too cool or ok  
   dT=spHC-act_T  ;delta Temp - difference between set and actual
   if dT>1000 then
    dT=1000  ;limit difference for the sake of integral maths to follow
   endif
     SerTxD ("delta Temp: ", #dT, 13, 10 ) ;send heat chamber temperature
   P=kP * dT   ;Proportional component
   P=P/10   ;normalise to % power
   if P < 100 then
    'we adjust integral
    if I<195 then
     I=I + kI   ;Integral component
     SerTxD ("Increasing I: ", #I , 13, 10 ) ;send heat chamber temperature
    endif
   endif
  endif
  
  if P>100 then
   P=100 'limit to maximum power
  endif
  
  if I>100 then
   'I is adding power
   normI=I-100
   iHC_ON= P + normI  ;Proportional + integral
   if iHC_ON >100 then
    iHC_ON=100
   endif
  else
   'I is decreasing power
   normI=100-I
   if P>normI then
    iHC_ON=P - normI
   else
    iHC_ON=0
   endif
  endif
  
 endif
SerTxD ("norm I: ", #normI , 13, 10 ) ;send heat chamber temperature
SerTxD ("P: ", #P , 13, 10 ) ;send heat chamber temperature
SerTxD ("I: ", #I , 13, 10 ) ;send heat chamber temperature
SerTxD ("PI: ", #iHC_ON , 13, 10 ) ;send heat chamber temperature
iHC_OFF=100-iHC_ON ;new duty cylce is loaded
 
goto main  
 
 
09 เมษายน

Reviewing HERMAN control architecture (PICAXE)

Quite some time ago I decided on the following networking arrangement for HERMAN control using the picaxe microprocessor.
 
  • Each module does all that is necessary for a localised task.
    • Tasks are separated into these discrete blocks of responsibility: Tun controllers (Mash, Hot Liquor, Heat Chamber, Kettle); Valve controllers (for each controllable ball, gate or solenoid liquor valve); Display controller; miscellaneous controllers as needed (such as hop dropper).
    • This means that a tun control module (for example hot liquor) needs to read liquor temperatures, level of liquor, and be able to control the heating element as a stand alone system.
  • Each module is biased to be verbose in its network reporting.
    • When a module records a change in a sensor, that information is reported on the network bus
    • Module handshaking is done via a clear to send line - a module will send information at the earliest clear opportunity
    • Modules take the initiative in sending information.
  • A PC connected to the network may operate as a network controller.
    • While each module operates as a stand alone unit, the PC is capable of coordinating tasks. A complex task might be controlling valves to fill the hot liquor tun, and sensing when that tun is full, and then stopping the fill.
  • A PC on the network only sends information on the network occasionally
    • Minimising traffic to the modules will minimise "interuptions" to normal module processing.
    • The task of coordination is not complex in terms of information flow, so communication only needs to be occasional.
  • A dedicated Picaxe module may be employed in place of the PC as a network controller
    • This unit would monitor network traffic to provide information display
    • This unit would coordinate tasks across modules as per the PC
    • Ideally the PC and this module would be able to work together

To achieve these aims, processes that 'distract' a module from performing its normal work is minimised. There are a number of picaxe related issues that need to be resolved:

    • potential 'lock-up' of serial in communications
    • time delays during serial-in communications if this is frequent
    • 750mS time delays in reading DS18B20 temperature probes

Minimising the serial in communications has already been mentioned. Given the recent announcement of the X1 range of picaxe chips, it would appear that a 28X1 is an ideal candidate for a picaxe network controller. The scratch pad and background serial communications features mean it is likely an ideal buffer for PC communications, should a PC be optionally attached as a network controller. The added timer functions suggest it may be possible to ultimately code an X1 as a fully automated controller.

Synchronisation issues regarding serial in on the remaining modules would be minimised with a serial break sent by the PC/picaxe controller that triggers interrupts on these modules.

It has taken some time to work through temperature sensing issues. I have long liked the simple accuracy of the DS18B20s but have not been happy with the reading delay time that has caused picaxe chips to wait for 750mS until a response is received. Analog probes are quick to read, but generally need to be amplified to get the accuracy I've desired. Jurgen Kranenborg has provided the inspiration needed in his article on 2-wire networking (see previous blog).

Where I had originally been planning discrete connections from the tun module picaxes to temperature and level sensors, this can now be simplified in architecture by connecting these to a sub-network. This architecture also solves the 750mS processing delay problem by using additional 08M picaxe chips as sensor buffers. The tun (or other) module can address a particular sensor and request information, and after an appropriate time delay can then read that information. Using a sub-network adds versatility. This could mean that temperature analysis could be simple or complex using the same physical architecture. As mentioned in the 'Further musing on temperature sensing' blog, the heat chamber might benefit from complex temperature analysis, while the hot liquor tun may only require simple temperature measurements.

This sub-network idea could also prove useful for level measurement. It may turn out that the accuracy of a capacitive sensor would be enhanced with a long 'count' time compared to a short one. A process of requesting, continuing processing, and reading the result may be advantageous.

A sub-network may also be useful for adding extra display information. Each tun module could benefit from having a 3 digit LED display that shows either temperature or power levels. While this information may be available on the picaxe controller LCD, a local display may prove more practical.

01 มีนาคม

Picaxe controllers

The picaxe range of controllers from Revolution Education are capable of many wonderful things and have already had a significant role in my home brewery. I give an introduction to them on my web site here: http://users.tpg.com.au/adsl2y58/userfiles/html/picaxe.htm
 
This blog explores the types of things that these controllers are capable of, and some of the pitfalls to look out for. When I built the HERMAN 5 control board (which is still in use) I had only a basic understanding of what these devices were capable of, and, more importantly, what their limitations were. Their ease of programming and use still makes them desirable for a project like HERMAN, although the limitations often require work-arounds to ensure a fully functioning control system.
 
What I did not realise early on, is that when a picaxe looks for serial communications (in our case from a PC), it will not do anything else until it sees the right sequence of information. This means that while you might think it is checking temperatures or regulating the power on a heater, the device is actually doing nothing except look at the serial line. If coding is not right, this means a picaxe can actually 'lock up' forever. And I wondered why it could take four or five minutes to update some temperatures on my PC
 
Another significant issue is that the digital temperature probes that are ideally matched with the picaxe, the Dallas DS18B20s, take 750mS to do a read. I love these probes, but did not realise that the picaxe literally waits and does nothing else during the read time. This means while reading it cannot respond to serial communications, for example. With a picaxe board that tried to read 6 or so of these probes and respond to serial communications, it was no wonder that things got out of sync and could take minutes to respond.
 
There are many workarounds to these limitations, and Hippy has some great documentation on his site:
 
There is also light on the horizon as RevEd are soon to release an X2 series of chips that will be much more powerful and promise to eliminate these wait/freeze issues. Details on this remain sketchy though, and they have not been able to keep to schedule through some chip manufacturing issues.
 
HERMAN 6 control has been designed to workaround these issues. Where feasible, analog temperature probes will be used, thus avoiding the 750mS delay in reading. The hardware has been designed with both digital and analog probes available so that X2s can be used on the boards should they work as hoped. All modules will spend minimal time receiving serial communications. The PC will only send occasional commands, and occasionally ask for status information. Modules will work on their own control routines until an interrupt triggers serial receive mode. The modules will basically do their own thing and only change if instructed. Serial output communication is not a problem in the same way, so the modules will send any information that has changed back to the PC. The final design consideration in light of these workarounds is that each module will only have a maximum of one digital temperature probe.
 
The picture I've added to this blog is of the current 40x control board - not pretty, but it still works.
 
I've written a design document that contains a lot of information. I'll go through it and see what is relevant to post here. I will also begin to document each module with circuits and coding as I get the time to do so.