Automated Aeropress Coffee Machine

This was the main project of the Mechanics & Electronics module at Loughborugh University in my final year. Despite being a piss poor module which came under fire from our entire cohort, the outcome was rather fun. The brief was to design a device that would automagically plunge an Aeropress coffee maker (with as much pizazz as possible).

The result was a voice activated, self-inverting, X winged plunger that used the inverted Aeropress brewing method. It’s even equipped with a surprisingly intelligent homing sequence in the case of power loss – or emergency shutdown in the face of imminent finger loss.

This was a group project, but since the teaching was so poor that no one else had any clue what was going on, I took the managerial role – having the most experience with electronics so far. Initially we each came up with a design, then chose our favourite to take forward to the manufacturing stage. We chose my design, so I was head of design/CAD, coding and final assembly/debugging. Izzy headed up machine learning and voice control. Bii and Taz wrote the bulk of the report and did a lot of the boring box ticking exercises needed to score marks – as well as manufacturing the laser and water jet cut parts. Big thanks to those guys for doing all the bits I didn’t want to do – you’re heroes.

PIC 18F45K20 C Code:

/** GROUP B AEROPRESS X-PLUNGE CODE ******************

BY TASMIN WHITTLE, BII TARTAGLIA, IZABELLA MICO & MAX JACOBY - 2023-24

THIS CODE MAKES COFFEE IN A CONTRIVED WAY.

*/
/** C O N F I G U R A T I O N   B I T S ******************************/

#pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF                      // CONFIG1H
#pragma config PWRT = OFF, BOREN = OFF, BORV = 30                           // CONFIG2L
#pragma config WDTEN = OFF, WDTPS = 32768                                   // CONFIG2H
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTBE      // CONFIG3H
#pragma config STVREN = ON, LVP = OFF, XINST = OFF                          // CONFIG4L
#pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF                   // CONFIG5L
#pragma config CPB = OFF, CPD = OFF                                         // CONFIG5H
#pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF               // CONFIG6L
#pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF                           // CONFIG6H
#pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF           // CONFIG7L
#pragma config EBTRB = OFF                                                  // CONFIG7H

/** I N C L U D E S **************************************************/

#include "p18f45k20.h"
#include <delays.h>

/** D E C L A R A T I O N S ******************************************/

#pragma udata // declare statically allocated uinitialized variables

/** D E F I N E S ****************************************************/

//Stepper Stuff--->
#define DIR_PIN PORTBbits.RB4  //stepper direciton
#define STEP_PIN PORTBbits.RB5 //stepper step
//<---Stepper Stuff

//LCD stuff--->
#define CLEAR_SCREEN  	0b00000001
#define FOUR_BIT  		0b00101100
#define LINES_5X7  		0b00111000
#define CURSOR_BLINK  	0b00001111
#define CURSOR_RIGHT  	0b00000110
#define DATA_PORT  LATD
#define RS_PIN     PORTCbits.RC6
#define E_PIN      PORTCbits.RC7
//<---LCD stuff

/** V A R I A B L E S ***********************************************/

int makingcoffee = 0;

/** F U N C T I O N S ***********************************************/

//INITIALIZATIONS--->
void initIO(void) {
    ANSEL  = 0;	          // set i/o to digital
    ANSELH = 0;           // set rest of i/o to digital
    TRISBbits.TRISB4 = 0; //steper dir
    TRISBbits.TRISB5 = 0; //stepper step
    TRISAbits.TRISA3 = 1; //stepper vertical microswitch
	TRISBbits.TRISB3 = 0; //plunge motor PWM out 2
    TRISAbits.TRISA4 = 1; //plunge limit
    TRISAbits.TRISA5 = 1; //unplunge limit
    TRISAbits.TRISA0 = 1; //user confirm
    TRISD = 0;
    TRISC = 0;            
    LATC   = 0b00000000;  // turns off port D outputs so display is blank
}
void initPWM(void) {
    T2CON = 0b00000111;
    PR2 = 249;
    CCP1CON = 0b01001100;
    CCP2CON = 0b01001100;
    CCPR1L = 0;
    CCPR2L = 0;
}
//<---INITIALIZATIONS

//PLUNGE CONTROL--->
void plungerev(void) {
        while (PORTAbits.RA5 == 1) { // Check up limit
            CCPR1L = 150;   // Set the duty cycle for unplunge (0-255)
        }
        CCPR1L = 0;      // Turn off motor when limit pressed
        CCPR2L = 25;
        Delay10KTCYx(10);
        CCPR2L = 0;
}

void plungefwd(void) {
        while (PORTAbits.RA4 == 1) {  // check down
            CCPR2L = 150;   // Set the duty cycle for plunge (0-255)
        }
        CCPR2L = 0;      // Turn off motor when limit pressed
}
//<---PLUNGE CONTROL

//ROTATION CONTROL--->
void setDirection(int direction) {
    DIR_PIN = direction;  // Set direction pin
}

void moveStepperMotor(int steps) {
    int i;
    for (i = 0; i < steps; i++) {
        STEP_PIN = 1;  // Set STEP pin high
        Delay10TCYx(10);  
        STEP_PIN = 0;  // Set STEP pin low
        Delay10TCYx(10);
    }
}
void unvert(void) {
    if(PORTAbits.RA3 == 1) {
        setDirection(1); //anticlockwise
        while(PORTAbits.RA3 == 1) {
            moveStepperMotor(1);
        }
    }
}
void invert(void) {
    unvert();
    if(PORTAbits.RA3 == 0) {
        setDirection(0); //clockwise
        moveStepperMotor(2600); //650 full step = 2600 1/4 microstep
     }
}
//<---ROTATION CONTROL

//HOME SEQUENCE--->
void home(void) {
    if(PORTAbits.RA3 == 1) {
        setDirection(1); //anticlockwise
        while(PORTAbits.RA3 == 1) {
            moveStepperMotor(1);
        }
    }
    plungerev();
}
//<---HOME SEQUENCE

//LCD--->
void Delay5milli(void)					    //Suitable delay for LCD
{
    Delay1KTCYx(2);           						
}

void SetAddr(unsigned char DDaddr)
{
    DATA_PORT &= 0xf0;                      // Write upper nibble
    DATA_PORT |= (((DDaddr | 0b10000000)>>4) & 0x0f);

    RS_PIN = 0;                             // Set control bit
    Delay5milli();
    E_PIN = 1;                              // Clock the cmd and address in
    Delay5milli();
    E_PIN = 0;

    DATA_PORT &= 0xf0;                      // Write lower nibble
    DATA_PORT |= (DDaddr&0x0f);

    Delay5milli();
    E_PIN = 1;                              // Clock the cmd and address in
    Delay5milli();
    E_PIN = 0;
}

void WriteCmd(unsigned char cmd)
{
    DATA_PORT &= 0xf0;
    DATA_PORT |= (cmd>>4)&0x0f;           
    RS_PIN = 0;                     		// Set control signals for command
    Delay5milli();
    E_PIN = 1;                      		// Clock command in
    Delay5milli();
    E_PIN = 0;

    DATA_PORT &= 0xf0;              		// Lower nibble interface
    DATA_PORT |= cmd&0x0f;
    Delay5milli();
    E_PIN = 1;                      		// Clock command in
    Delay5milli();
    E_PIN = 0;
}

void WriteChar(char data)
{
    DATA_PORT &= 0xf0;
    DATA_PORT |= ((data>>4)&0x0f);

    RS_PIN = 1;                     		// Set control bits
    Delay5milli();
    E_PIN = 1;                      		// Clock nibble into LCD
    Delay5milli();
    E_PIN = 0;

    DATA_PORT &= 0xf0;              		// Lower nibble interface
    DATA_PORT |= (data&0x0f);

    Delay5milli();
    E_PIN = 1;                      		// Clock nibble into LCD
    Delay5milli();
    E_PIN = 0;
}

void WriteString(const rom char *buffer)    
{		 
    while(*buffer)                  		// Write data to LCD up to null
    {
        Delay5milli();
        WriteChar( *buffer);          		// Write character to LCD
        buffer++;                     		// Increment buffer
    }
    return;
}
void initLCD(void)
{
    WriteCmd ( 0x02 );							// sets 4bit operation
    WriteCmd ( CLEAR_SCREEN );                  // clears the screen
    WriteCmd ( FOUR_BIT & LINES_5X7 );			// sets 5x7 and multiline operation.
    //programFlame();                             // write the custom flame characters to the LCD
    WriteCmd ( CURSOR_BLINK );					// blinks cursor
    WriteCmd ( CURSOR_RIGHT  );					// moves cursor right	
}
void progMugAni(void) {
    SetAddr	 ( 0x00 );
	WriteChar ( 0x00 );
	WriteChar ( 0x01 );
	WriteChar ( 0x02 );
	WriteChar ( 0x03 );
	WriteChar ( 0x04 );
	WriteChar ( 0x05 );
	WriteChar ( 0x06 );
	WriteChar ( 0x07 );
	WriteCmd  ( 0x40 );							// writing to display
	WriteCmd  ( 0b00001011);	//display off
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000010 );					// first character
	WriteChar ( 0b00000010 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );					// second character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );					// third character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001111 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010100 );					// fourth character
	WriteChar ( 0b00010100 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001001 );					// fifth character
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );					// sixth character
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteCmd  ( 0b00001100);	//display back on
	WriteCmd  ( CLEAR_SCREEN);    
}
void mugAni(void) { //loop the mug placed animation  
    while(PORTAbits.RA0 == 0) {
    SetAddr (0x80); 							// coffee mug animation first frame
    WriteChar ( 0x00 );
    WriteChar ( 0x01 );
    WriteString("is the mug on");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x02 );
    WriteChar ( 0x03 );
    WriteString("the platform?");
    Delay10KTCYx(10); 							// keeps message on screen 
    SetAddr (0x80); 							// flame animation second frame
    WriteChar ( 0x04 );
    WriteChar ( 0x05 );
    WriteString("is the mug on");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x02 );
    WriteChar ( 0x03 );
    WriteString("the platform?");
    Delay10KTCYx(10); 							// keeps message on screen
    }
}
void progCoffeeAni(void) {
    SetAddr	 ( 0x00 );
	WriteChar ( 0x00 );
	WriteChar ( 0x01 );
	WriteChar ( 0x02 );
	WriteChar ( 0x03 );
	WriteChar ( 0x04 );
	WriteChar ( 0x05 );
	WriteChar ( 0x06 );
	WriteChar ( 0x07 );
	WriteCmd  ( 0x40 );							// writing to display
	WriteCmd  ( 0b00001011);	//display off
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000010 );					// first character
	WriteChar ( 0b00000010 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );					// second character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );					// third character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001111 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010100 );					// fourth character
	WriteChar ( 0b00010100 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001001 );					// fifth character
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );					// sixth character
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteCmd  ( 0b00001100);	//display back on
	WriteCmd  ( CLEAR_SCREEN);  
}
void coffeeAni(void) { //program and loop add coffee and water animation   
    while(PORTAbits.RA0 == 0) {
    SetAddr (0x80); 							// coffee mug animation first frame
    WriteChar ( 0x00 );
    WriteChar ( 0x01 );
    WriteString("are the coffee and");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x02 );
    WriteChar ( 0x03 );
    WriteString("water poured?");
    Delay10KTCYx(10); 							// keeps message on screen 
    SetAddr (0x80); 							// flame animation second frame
    WriteChar ( 0x04 );
    WriteChar ( 0x05 );
    WriteString("are the coffee and");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x06 );
    WriteChar ( 0x07 );
    WriteString("water poured?");
    Delay10KTCYx(10); 							// keeps message on screen 		
    }
}
void progFilterAni(void) {
    SetAddr	 ( 0x00 );
	WriteChar ( 0x00 );
	WriteChar ( 0x01 );
	WriteChar ( 0x02 );
	WriteChar ( 0x03 );
	WriteChar ( 0x04 );
	WriteChar ( 0x05 );
	WriteChar ( 0x06 );
	WriteChar ( 0x07 );
	WriteCmd  ( 0x40 );							// writing to display
	WriteCmd  ( 0b00001011);	//display off
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000010 );					// first character
	WriteChar ( 0b00000010 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );					// second character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );					// third character
    WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001111 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010100 );					// fourth character
	WriteChar ( 0b00010100 );
    WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001001 );					// fifth character
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );					// sixth character
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteCmd  ( 0b00001100);	//display back on
	WriteCmd  ( CLEAR_SCREEN);    
}
void filterAni(void) { //program and look filter animation  
    while(PORTAbits.RA0 == 0) {
    SetAddr (0x80); 							// coffee mug animation first frame
    WriteChar ( 0x00 );
    WriteChar ( 0x01 );
    WriteString("is the filter cap");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x02 );
    WriteChar ( 0x03 );  
    WriteString("installed?");
    Delay10KTCYx(10); 							// keeps message on screen 
    SetAddr (0x80); 							// flame animation second frame
    WriteChar ( 0x04 );
    WriteChar ( 0x05 );
    WriteString("is the filter cap");
    SetAddr (0xC0);                             // moves character to begining of second line
    WriteChar ( 0x02 );
    WriteChar ( 0x03 );
    WriteString("installed?");
    Delay10KTCYx(10); 							// keeps message on screen 		
    }
}
void progBrewingAni(void) {
    SetAddr	 ( 0x00 );
	WriteChar ( 0x00 );
	WriteChar ( 0x01 );
	WriteChar ( 0x02 );
	WriteChar ( 0x03 );
	WriteChar ( 0x04 );
	WriteChar ( 0x05 );
	WriteChar ( 0x06 );
	WriteChar ( 0x07 );
	WriteCmd  ( 0x40 );							// writing to display
	WriteCmd  ( 0b00001011);	//display off
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000010 );					// first character
	WriteChar ( 0b00000010 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );					// second character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );					// third character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001111 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010100 );					// fourth character
	WriteChar ( 0b00010100 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001001 );					// fifth character
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );					// sixth character
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteCmd  ( 0b00001100);	//display back on
	WriteCmd  ( CLEAR_SCREEN);    
}
void brewingAni(int loops) { //programs and looks brewing animation
    int j;
    for (j = 0; j < loops; j++) {
        SetAddr (0x80); 							// coffee mug animation first frame
        WriteChar ( 0x00 );
        WriteChar ( 0x01 );
        WriteString("ready to");
        SetAddr (0xC0);                             // moves character to begining of second line
        WriteChar ( 0x02 );
        WriteChar ( 0x03 );
        WriteString("start brew?");
        Delay10KTCYx(10); 							// keeps message on screen 
        SetAddr (0x80); 							// flame animation second frame
        WriteChar ( 0x04 );
        WriteChar ( 0x05 );
        WriteString("ready to");
        SetAddr (0xC0);                             // moves character to begining of second line
        WriteChar ( 0x02 );
        WriteChar ( 0x03 );
        WriteString("start brew?");
        Delay10KTCYx(10); 							// keeps message on screen 			
    }
}
void progFinishedAni(void) {
    SetAddr	 ( 0x00 );
	WriteChar ( 0x00 );
	WriteChar ( 0x01 );
	WriteChar ( 0x02 );
	WriteChar ( 0x03 );
	WriteChar ( 0x04 );
	WriteChar ( 0x05 );
	WriteChar ( 0x06 );
	WriteChar ( 0x07 );
	WriteCmd  ( 0x40 );							// writing to display
	WriteCmd  ( 0b00001011);	//display off
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000010 );					// first character
	WriteChar ( 0b00000010 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );					// second character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );					// third character
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001111 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010100 );					// fourth character
	WriteChar ( 0b00010100 );
	WriteChar ( 0b00011100 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00001001 );					// fifth character
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00000100 );
	WriteChar ( 0b00000101 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00011111 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );					// sixth character
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00001000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00000000 );
	WriteChar ( 0b00010000 );
	WriteChar ( 0b00011100 );
	WriteCmd  ( 0b00001100);	//display back on
	WriteCmd  ( CLEAR_SCREEN);         
}
void finishedAni(int loops) {
    int k;
    for (k = 0; k < loops; k++) {
        SetAddr (0x80); 							// coffee mug animation first frame
        WriteChar ( 0x00 );
        WriteChar ( 0x01 );
        WriteString("brewing");
        SetAddr (0xC0);                             // moves character to begining of second line
        WriteChar ( 0x02 );
        WriteChar ( 0x03 );
        WriteString("finished...");
        Delay10KTCYx(10); 							// keeps message on screen 
        SetAddr (0x80); 							// flame animation second frame
        WriteChar ( 0x04 );
        WriteChar ( 0x05 );
        WriteString("enjoy your");
        SetAddr (0xC0);                             // moves character to begining of second line
        WriteChar ( 0x02 );
        WriteChar ( 0x03 );
        WriteString("coffee!");
        Delay10KTCYx(10); 							// keeps message on screen 			
    }
}
//<---LCD

/** M A I N ***********************************************/

void main(void) {
    initIO();
    initPWM();
    initLCD();
    WriteString("welcome");                      // test the lcd and show the program is running
    SetAddr (0xC0);
    WriteString("cafeine fiend");
    Delay1KTCYx(200);
    WriteCmd( CLEAR_SCREEN );
    WriteString("stay clear");
    SetAddr (0xC0);
    WriteString("homing in... ");
    WriteChar(0x30 + 3);
    Delay1KTCYx(200);
    SetAddr (0xC0);
    WriteString("homing in... ");
    WriteChar(0x30 + 2);
    Delay1KTCYx(200);
    SetAddr (0xC0);
    WriteString("homing in... ");
    WriteChar(0x30 + 1);
    Delay1KTCYx(200);
    WriteCmd( CLEAR_SCREEN );
    WriteString("homing now");
    home();
    SetAddr (0xC0);
    WriteString("done");
    Delay1KTCYx(400);
    start:
    WriteCmd( CLEAR_SCREEN );
    progMugAni();
    mugAni();
    //progCoffeeAni();
    while(PORTAbits.RA0 == 1) {
    }
    coffeeAni();
    //progFilterAni();
    while(PORTAbits.RA0 == 1) {
    }   
    filterAni();    
    //progBrewingAni();
    brewingAni(4);
    WriteCmd( CLEAR_SCREEN );
    WriteString("brewing!");
    Delay1KTCYx(200);
    WriteString("steeping...");
    Delay10KTCYx(250);
    makingcoffee = 1;
    invert();
    Delay1KTCYx(200);
    plungefwd();
    Delay10KTCYx(100);
    unvert();
    Delay1KTCYx(200);
    plungerev();
    makingcoffee = 0;
    //progFinishedAni();
    finishedAni(6);
    goto start;
}

MORE LIKE THIS:

Cortical Archival System

sounds way cooler than “AI note taker” CLICK TO WATCH MY INSTAGRAM AND UNDERSTAND THIS! The following was transcribed and corrected by my program – 

Read more >

HOMELAB ’24

My collection of servers is still going strong and has evolved massively since my last post about my homelab in 2021. It’s now less of

Read more >