Friday, March 11, 2016

Washing Machine Controller Using AVR ATMEL ATmega8 Microcontroller Using Assembly Language (NOT Arduino)

Washing Machine Controller Using  AVR ATMEL ATmega8 Microcontroller Using Assembly Language (NOT Arduino)

A brief history about why I decided to make my own controller :-

I have a washing machine, with control board problems. I did changed the control board from OEM 2 times, each time it cost Rs.3900 + 300 for service charges. So, I spent Rs.8200/- since 2008. Actual machine cost is Rs.12,000/- Now in year 2016 the same control board SMPS failure . The washing machine model is Whirlpool Splash 55. Seems the designer of the board is a beer addict during design ! Very sad that not only for me for those having this model is having the same issue!!!. But this time I'm decided to design my own control board with my experiences. My control board costs less than Rs.500 and all of the components are from my junk box. not spent a paisa but time.

 

 Basic operation sequence of a washing machine :-

There is just 4 relays to be controlled in a regular sequence, not a rocket science either. The basic operation sequence is like this
  1. Water filling (at actual time)
  2. Agitronic soak (15mins)
  3. First wash    (15mins)
  4. First drain (4mins)
  5. Second wash or call it as first rinse (10mins)
  6. Second drain (4mins)
  7. Spin (5mins)
  8. Buzzer chim (15sec)
There are lot of  information available about the time taken for each operation from several washing machine manufacturer. But i referred Whirlpools manual and it recommends as below
Program Time / Cycle time for each mode
                     All values in minutes
                 Agitronic    Normal    Speedy    R+S    S only
 Soak            20            -                  -         -            -
 Wash           20          20                 9          -            -  
 Rinse           16          16               16         8             -
 Spin              8           8                  6         6             6
And there is a very nice recommendation from Bureau Of Energy Efficiency
Energy Labeling Scheme For Washing Machines by Bureau Of Energy Efficiency
https://www.beestarlabel.com/Content/Files/Schedule12-WM.pdf

From the above given recommendation i choose  following timings
   soakTime     = 15 mins
   washTime     = 15 mins (For one wash cycle)
   rinseTime     =  8 mins
   spinTime     =  5 mins
At this point of time, there is no selector / program selector available on the controller. But it's on my wish list.

Why decided to use AVR Assembly language and not to use Arduino C

For this washing machine controller i decided to use assembly language, and it'll be my first AVR assembly language project. I'm using AVR Studio 4.19 and ProgISP to compile and upload.
I personally do not recommend higher version of AVR Studio. V 4.19 is lite and there is not much improvement on ASM compiler between V4.19 and V6.2. (Both IDE's assembler version is 2.1.xx)
Since 2006 i'm using Arduino, now i'm feeling limited with arduino resources when there is really a lot of things can be done with AVRs other line of products like ATtiny13, 2313, etc....Arduino will not help to develop codes for this. The size of HEX code for LedBlink in arduino is 890 bytes, the same LedBlink in assembly will be just 34 bytes !!!! Wow ahh.. Excess  856 bytes of code dumped inside my ATmega8 for nothing. When comes to industrial application the unwanted junk of code will generate lot of issues. That's why the Arduino's liquidCrystal library is not recommended by most of developers as it collide with interrupt cycle or millis() library.
Arduino is for kids and new comers. For real time application Arduino is not the right tool to write my code. Best to go for ASM Assembly language for AVR.

Hardware setup

I had my own ATmega8 break out board with 6 inputs and 4 outputs. I'm using this pcbs for most of my project. Here is the schematic diagram of controller.

Inputs

Water level pressure switch
Loading door open / close switch. (in my project, i'm not using this sensor)

Outputs

Buzzer
Motor forward
Motor reverse
Water inlet solenoid
Water drain traction motor
           ( In my model Whirlpool Splash 55, Its single motor for slow spin and fast spin, it's the drain traction motor change the gear wheel between slow and fast spin )
Wish list : heartbeat LED, sequence indication LEDs, start / pause button, EEPROM storage of electricity failure recovery, etc...

Here is my complete source code in ASM language  for ATMEL ATmega8 controlled Washing Machine
 AVR-ATMEL-ATmega8-Microcontroller-controllerd-washing-machine- Using-Assembly-Language.asm

Complete project file in zip file (asm, HEX, etc..)
AVR-ATMEL-ATmega8-Microcontroller-controllerd-washing-machine- Using-Assembly-Language

/************************************************************************************
* This program is to control WhirlPool Washing machine with 6 Kg capacity        *
* Using ATmega8 and 1MHz internal oscillator & 1/1024 timer0 prescaler            *
* Devloped by Ram Sankar Pillai    email: ramvsankar AT gmail dot com            *   
* Date started 10-Feb-2016                                        *
* Washine machine Model : Whirlpool, Splash 6Kg (Indian version)                *   
* timer over flow interrupt method                                    *
* trial and error method                                        *
* Definitely there will be a better way to do program                        *
* Any suggestions welcome                                        *
* delay in seconds and minutes should not exceed 60                        *
*    soakTime     = 15 mins                                        *
*    washTime     = 15 mins (For one wash cycle)                         *
*    rinseTime     =  8 mins                                        *
*    spinTime     =  5 mins                                        *            
*************************************************************************************
*                                                        *
* This program is free software. you can redistribute it and/or                *
* modify it under the terms of the GNU General Public License.                *
* This program is distributed in the hope that it will be useful,                *
* but WITHOUT ANY WARRANTY                                        *
*************************************************************************************
*/
.nolist
.include "m8def.inc" ;(include ATmega8 definitions)
.list

.def     A         =     R16    ;General purpose accumulators
.def    B        =    R17
.def    C        =    R18    ; to hold preloader value
.def    counter    =    R19
.def    seconds    =    R20
.def    minutes    =    R21
.def    oneTenthSec    =    R22
.def    targetSec    =    R23
.def    targetMin    =    R24
.def    targetOneTenthSec    =    R25


.equ    preloadTimer    =    165 ; Change this value according to oscillator error
.equ    pressureSensorPin    =    PC1   
.equ    inletValvePin    =    PB4
.equ    drainValvePin    =    PB3
.equ    drumFwdPin        =    PB2
.equ    drumRevPin        =    PB1
.equ    buzzerPin        =    PB0

.ORG 0x000    RJMP onReset ;RESET VECTOR
.ORG 0x009    RJMP timerOverFlow ; Timer0 Overflow Handler

;***********************************
; TIMER OVER-FLOW INTERUPT ROUTINE *
;***********************************
timerOverFlow:
    inc    counter
    LDI     C, preloadTimer     ;PRELOAD THE TIMER
    OUT     TCNT0, C
    RETI
;************************************************
;     Macro for ONE TENTH of A SECOND delay    *
;************************************************
.macro delayOneTenthSec
    ldi    targetOneTenthSec, @0
    ldi    counter, 0
oneTenthSecStart:
    ; @ 165 in TCNT0 and 1024 prescale and 1MHz osc
    cpi     counter, 1    ; 1 represents 1/10 second
    brlo    oneTenthSecStart
    ldi    counter, 0
    inc     oneTenthSec
    cp    oneTenthSec, targetOneTenthSec
    brne    oneTenthSecStart
    ldi     oneTenthSec, 0
.endmacro
;************************************
;     Macro for ONE SECOND delay    *
;************************************
.macro delaySecs
    ldi    targetSec, @0
    ldi    counter, 0
secStart:
    ; @ 165 in TCNT0 and 1024 prescale and 1MHz osc
    cpi     counter, 10    ; 10 represents 1 second
    brlo    secStart
    ldi    counter, 0
    inc     seconds
    cp    seconds, targetSec    ; check for 1 minute
    brne    secStart
    ldi     seconds, 0
.endmacro
;************************************
;     Macro for ONE MINUTE delay    *
;************************************
.macro delayMins
    ldi    targetMin, @0
    ldi    minutes, 0
minStart:
    delaySecs(60);    set 60 for one minute
    inc     minutes
    cp    minutes, targetMin    ; check for 1 minute
    brne    minStart
    ldi     minutes, 0
.endmacro

;************************************************************
;        Microcontroller Initiation Procedure        *
;************************************************************
onReset:
    ldi    A, HIGH(RAMEND)
    out    SPH, A
    ldi    A, LOW(RAMEND)
    out    SPL, A
    ldi     A,    0b00000101 ;SET PRESCALER TO /1024
    out     TCCR0, A         ;TIMER/COUNTER CONTROL REGISTER
    ldi     A,    0b0000_0001 ;ENABLE TIMER-OVERFLOW INTERUPT
    out     TIMSK, A
    ldi     C,preloadTimer     ;PRELOAD THE TIMER
    out     TCNT0, C
    ldi    seconds, 0
    ldi    counter, 0
    ldi    oneTenthSec, 0
    sei                 ;ENABLE INTERUPTS GLOBALLY

    cbi    DDRC, pressureSensorPin
    sbi    PORTC, pressureSensorPin
    ldi    A, 0b0011_1111    ; PB1,2,3,4,5 as OUTPUTs
    out    DDRB,    A
    ldi    A, 0x00        ; All outputs LOW
    out    PORTB, A
   
;************************************************************
;        Main Program STARTS Here                *
;************************************************************
   
mainLoop:
    sbi    PORTB, buzzerPin    ; Power ON indication
    delayOneTenthSec(7);
    cbi    PORTB, buzzerPin
    rcall waterFilling    ; Water filling subroutine
     rcall agitronicSoak    ; Soak subroutine
      rcall firstWashing    ; 1st wash subroutine, with 3 mins delay
      rcall draining        ; 1st drain water subroutine
      rcall waterFilling    ; Water filling subroutine
    rcall secondWashing    ; 2nd wash subroutine, with 1 min delay
      rcall draining        ; 2nd drain water subroutine
      rcall spinning        ; spin subroutine   
    rcall    chiming        ; Chiming subroutine   
endlessLoop:
    RJMP endlessLoop
   
;************************************************************
;            Main Program ENDS Here                *
;************************************************************

;***************** Water Filling sequence *******************
waterFilling:
    cbi    PORTB, drainValvePin
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    sbi    PORTB, inletValvePin
waterCheck:
    sbic    PINC,  pressureSensorPin
    rjmp waterCheck
    cbi    PORTB, inletValvePin
    RET

;************ Agitronic Soak sequence starts here ***************
agitronicSoak:
    cbi    PORTB, drainValvePin
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    cbi    PORTB, inletValvePin
    ldi    A, 0
soakAgain:
    cpi    A, 5    ; change this to increase or decrease no cycles
    breq    agitronicEnd
    rcall pulsatingSpin
    delayMins(3) ; changed here to reduce cycle time
    inc A
    rjmp soakAgain
agitronicEnd:
    RET

;*********** delay sequence during agitronic soak ***************
pulsatingSpin:
    sbi    PORTB, drumFwdPin    ; drum rotates FWD for 2 secs
    delaySecs(2)       
    cbi    PORTB, drumFwdPin
    delaySecs(1)        ; Dwell for 1 sec
    sbi    PORTB, drumRevPin    ; and rotate REV for 2 secs
    delaySecs(2)
    cbi    PORTB, drumRevPin
    delaySecs(1)        ; Dwell for 1 sec
    RET

;*********** Washing sequence starts here ***************
firstWashing:
    cbi    PORTB, drainValvePin
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    cbi    PORTB, inletValvePin
    ldi    A, 0
washAgain:
    cpi    A, 5         ;change this to increase or decrease no cycles
    breq    washingEnd
    rcall    pulsatingWashSlow
    rcall    pulsatingWashFast
    delayMins(3)    ; changed here to reduce cycle time
    inc A   
    rjmp    washAgain
washingEnd:           
    RET
;*********** Washing sequence starts here ***************
secondWashing:
    cbi    PORTB, drainValvePin
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    cbi    PORTB, inletValvePin
    ldi    A, 0
secondWashAgain:
    cpi    A, 5         ;change this to increase or decrease no cycles
    breq    secondWashingEnd
    rcall    pulsatingWashSlow
    rcall    pulsatingWashFast
    delayMins(1)    ; changed here to reduce cycle time
    inc A   
    rjmp    secondWashAgain
secondWashingEnd:           
    RET
;*********** Pulsating wash SLOW subroutine ***************
pulsatingWashSlow:    ; do this for 10 times at an interval of 3 mins
    ldi    B, 0
slowAgain:
    cpi    B, 12    ;  change this to increase or decrease no cycles
    breq    pulsatingWashSlowEnd
    sbi    PORTB, drumFwdPin
    delaySecs(2)
    cbi    PORTB, drumFwdPin
    delayOneTenthSec(7)
    sbi    PORTB, drumRevPin
    delaySecs(2)
    cbi    PORTB, drumRevPin
    delayOneTenthSec(7)
    inc     B
    rjmp    slowAgain
pulsatingWashSlowEnd:   
    RET

;*********** Pulsating wash FAST subroutine ***************
pulsatingWashFast:    ; do this for 12 times at an interval of 3 mins
    ldi    B, 0
fastAgain:
    cpi    B, 12        ; change this to increase or decrease no cycles
    breq    pulsatingWashFastEnd
    sbi    PORTB, drumFwdPin
    delaySecs(1)
    cbi    PORTB, drumFwdPin
    delayOneTenthSec(3)
    sbi    PORTB, drumRevPin
    delaySecs(1)
    cbi    PORTB, drumRevPin
    delayOneTenthSec(3)
    inc     B
    rjmp    fastAgain
pulsatingWashFastEnd:   
    RET

;*********** Drain sequence subroutine ***************
draining:        ; 1st drain water
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    cbi    PORTB, inletValvePin
    sbi    PORTB, drainValvePin ; drain valve ON
    delaySecs(10)    ; delay for tracton motor to pull drain valve completely and gear engagement
drainCheck:
    sbic    PINC,  pressureSensorPin ; Check for water level if low then delay another 4mins
    rjmp drainCheck   
    delayMins(4)    ; 4 mins delay time to drain all water
    RET

;*********** Spin sequence subroutine ***************
spinning:        ; spin
    cbi    PORTB, drumFwdPin
    cbi    PORTB, drumRevPin
    cbi    PORTB, inletValvePin
    sbi    PORTB, drainValvePin ; drain valve ON
    delaySecs(10)    ; delay for tracton motor to pull drain valve completely
    sbi    PORTB, drumFwdPin ; small interrupt rotation for drum weight balancing
    delaySecs(8)
    cbi    PORTB, drumFwdPin
    delaySecs(4)        ; small interrupt rotation for drum weight balancing
    sbi    PORTB, drumFwdPin
    delaySecs(8)
    cbi    PORTB, drumFwdPin
    delaySecs(4)
    sbi    PORTB, drumFwdPin
    delayMins(5)    ; change here to reduce cycle time
    cbi    PORTB, drumFwdPin
    delaySecs(10)
    cbi    PORTB, drainValvePin
    RET
;*********** Chiming sequence subroutine ***************
chiming:    ; 20 times beep sound indication of cycle end
    ldi    A, 0
chimAgain:
    cpi    A, 20
    breq    chimingEnd
    sbi    PORTB, buzzerPin
    delayOneTenthSec(3)
    cbi    PORTB, buzzerPin
    delayOneTenthSec(1)
    inc     A
    rjmp chimAgain
chimingEnd:
    RET



4 comments:

  1. Lovely vu3xvr
    you are a rare person able to use the knowledge with all love for the technology.
    wish you many more projects likewise.
    73s
    de
    sarma
    vu3zmv

    ReplyDelete
  2. Excellent! Really useful. Dr.Rajasekhar, VU2HMY

    ReplyDelete
  3. Very nice article.

    ReplyDelete
  4. الان مع اسرع فريق صيانة متنقل من خلال مركز صيانة الكتروستار تواصلوا الان مع خدمة العملاء واحصلوا على كافة المميزات
    https://www.almyaa.com/Electrostar-Maintenance/

    ReplyDelete