CREMA Revision A – Prototype 1

So I’ve finished the board for CREMA Revision A – Prototype 1. It’s a beaut!

I’ll have it printed and wire it up. I can’t wait.

Unfortunately due to size constraints, all components are surface mount (to the exclusion of the Molex headers etc.) Fair warning: unless you have a reflow oven, soldering this board will not be for the faint of heart. There are no components smaller than a 0603 resistor so if you’re good with that, then this will be a breeze!

CREMA-Rev-A-Proto-1

The prototype has the following functions / features:

  • Dual P.I.D. Boiler Control (PWM based)
  • Dual PT100 RTD Temperature Sensors with 24-bit resolution providing 0.05°C temperature accuracy
  • Single Pump Control (PWM based: allows for pressure profiling)
  • 16×2 Display Module
  • Onboard real-time clock with two alarms
  • Bluetooth or WiFi (using Electric Imp) connectivity for remote control

Some of the design details include:

  • Onboard 5V 2,000mA power supply with resettable fuse and ESD protection
  • Faston Quick Connect tabs to be compatible with internal wiring of many espresso machines
  • Power indicator LEDs for Boiler A, Boiler B, and Pump solid state relays
  • Zero-crossing solid state relay to allow precise control of vibratory pumps
  • Line-voltage sensors to determine switch states without requiring any special wiring
  • Molex connectors with gold-plated pins to minimize connection problems

Once I work out any underlying bugs, I’ll firm-up the firmware :) and make a public release of the board.

Cheers!

CrystalFontz Library for Arduino

Some of you have asked for the library that I’ve made up for the CrystalFontz displays – so here it is!

The library, in its current state, is the bare minimum necessary to operate the display. I WILL be elaborating on it, and changing it around significantly in the final firmware revision.

You are free to use the library as you want, however I would appreciate an acknowledgement and a heads up on what you might be using the library for (to see what kind of cool stuff people are doing!).

Cheers!

CrystalFontz-Library-0.1

Arduino Leonardo – A Design Change

Pardon the delay! The past three months have been hectic with school and work. I’m finally taking some time over the holidays to get this project wrapped up.

I’m leaning towards implementing an Arduino Leonardo in place of a Pro Mini for two main reasons. The first is that the Leonardo has built-in USB support which frees up the UART for use with a Bluetooth module. The second major advantage is that the Leonardo actually has two 16-bit timers. While at first this may seem trivial, it in effect allows me precise control over the vibratory pump as well as boiler. Because the Crydom relay used to control both pump and boiler is a ‘zero-crossing’ relay, the relay can be toggled at 60Hz without the vibratory pump ‘stuttering’ – a full sinusoidal wave-form is allowed to pass through the relay before it latches on or off.

I can effectively control the pressure at the brew head by controlling the flow rate of water through the pump. Any standard duty cycle will work here (number of 60Hz cycles on to the number of 60Hz cycles off) allowing for precise control of pump activity. While the prescaler doesn’t allow for coincident timing at exactly 60Hz, the frequency discrepancy is so low (0.0961538 Hz) that a switching error (ie the Arduino pin would toggle at the zero crossing point, missing the step) almost never occurs in practice.

Timer (PWM) based control of the pump (Timer3), boiler (Timer1), and pin-change interrupts for the Brew (Pin 10 / PCINT6), Hot Water (Pin 11 / PCINT7) and Steam (Pin 8 / PCINT4) switches means that basic control over Silvia can be driven by interrupts instead of actively polling in the main loop. Additionally, the RTC interrupt pin on the DS3231 can drive Pin 7 / INT.6 allowing for a real-time clock based alarm / wakeup.

In short, the main body of code then will simply be to passively update the PID and Display module.

MID400 Line Sensor

So sorry about the long break in updating!

I’ve had a go at implementing the MID400 Line Voltage Sensor from Fairchild Semiconductor. The chip works as expected and really requires a minimal implementation. Basically I’d imagine three of these chips on the final board that will detect AC line levels from the main switches within Silvia. I’d imagine that in the final implementation, I’ll have ganged the output from each of the Quick Connect tabs so that we don’t have to worry about rewiring etc. (i.e., I’ll make a Male-Female-Female gang with the second Female tail connecting to the Duetto via a Quick Connect tab).

I suppose now the following pieces are outstanding: a plastic case / shell for the display, schematizing the final board, and finishing up the first major revision of the Duetto Firmware.

I’m really wrestling with how to implement an effective PID algorithm based on an input in one unit (in this case degrees Centigrade) and outputing a control value in a different unit (in this case, PWM value based on 15.625 kHz). So if anyone has any ideas – feel free to comment below!

This upcoming month is crazy for me with school, so it might very well take me a while before I’m able to dedicate any time to the Duetto project. Hang tight! I’m on it!

A Display That Doesn’t Press My Buttons …

I suppose this is a bit of a blessing in disguise but there are still a significant number of issues with the New Haven Displays. Recently, I sent the Version 2 displays back to New Haven to be reprogrammed with an updated firmware designed to eliminate flickering issues with the backlight. While the new firmware eliminates the flicker, it has also introduced a crippling bug in the displays ability to communicate properly – at least by I2C. For those who are interested in the details, the firmware does not handle a bus line release properly and appears not to be able to handle multi-byte transactions (such as in a custom-character write). Because there is currently no solution – nor is it my desire to debug their firmware – I have decided to go with a different display manufacturer.

I came across the CrystalFontz CFA533-TMI series of displays that provide the same 16×2 White on Blue display – with the added benefit of a built-in keypad. This is great as it frees up a significant number of pins on the Arduino, and eliminates the need for me to implement some sort of key-polling / response in the final software.

The price however is double. Moreover, the standard Arduino LCD libraries are not compatible with this display module. Whereas communication with most displays are unidirectional, communication with the CFA533 module is bi-directional. That is to say that you can send a command and then expect a response from the display (such as indicating the keys that are currently pressed, the keys that have been pressed since the last poll, and the keys that have been released since the last poll). The display also uses a CRC checksum after each command and with each response making communication a slightly more complicated (but less error prone) process.

To my knowledge, a C library or Arduino compatible library has not yet been written that supports this display – so I’ve written one myself. At present, the command set is limited to basic functions like clearing the display, writing text to the display, programming characters, and reading button states. I will release an alpha of the library in due time – when I’ve implemented enough of the command-set to be of use to others.

My initial response to the display module is that it’s great. It packs a fantastic feature set so the cost / benefit is worth it in my opinion.

More to come soon when I implement the Line Voltage sensors to detect Switch states. Oh my!

A Flicker of Hope!

I noticed a marked flicker in the Newhaven Display. It turns out, it’s a glitch in the firmware based on any active communication with the display. Luckily, Newhaven Display acknowledges this, and is willing to exchange / upgrade the firmware. Thank goodness!

I’m at a point where things are really starting to come together piece-wise. I have a few things left to test, including the MID400 line sensors to detect the rocker-switch status’. So far, I have the ADS1247 analog-to-digital converter, LCD display, DS3231M real-time clock, and solid-state relay integrated together. Theoretically, it could operate as an effective PID. But of course, I’m looking to implement much more before I put it to practice.

I’m also fussing around a bit with the code – trying to get everything neat and tidy as opposed to the rats nest that I’ve been using. I’m toying with different looks on the display and how to implement a lean yet effective visual menu.

You can see on the display, the first line is dynamic and displays the real-time clock, boiler status and current temperature (I’ve got a resistor in place to simulate the PT100). The second line of the display shows the custom characters that I’ve designed so far – the thermometer, “Brew”, “Hot Water”, and “Steam” icons. I intend for the latter three to activate as appropriate depending on the switch status.

I’m imagining two modes within the system – Automatic or Manual. In automatic mode, the system would wait for the brew switch to be thrown and then activate the pump. The system would then toggle the pump to control pre-infusion and extraction as programmed. In this mode, the three-way solenoid valve would remain engaged during the pre-infusion to prevent the pre-infusion from back-flushing through the solenoid valve. The solenoid valve disengages when the brew switch is turned off. In manual mode, the system will wait for the brew switch and engage the pump until the switch is turned off. Throwing the hot-water switch has much the same effect in both modes, except that the solenoid valve is not engaged. Switching temperature on the controller to a “steam” temperature (greater than 120°C) and throwing the steam switch will automatically pulse the pump to fill up the boiler. Of course there will be a number of programmable presets so that you can tailor pre-infusions and brew temperatures (or even tea temperatures!). These presets will be able to be set by “learning” how you operate the controls.

It might be a bit before I get the code worked out, but I suppose a few extra espressos might keep me on the ball.

Time and the DS3231M

Because the Arduino Pro Mini lacks the ability to accurately maintain time over extended periods of time, and because of the complexities of time-keeping, I decided to implement an external real-time clock (RTC). Ultimately I want Silvia to turn herself on, and warm up to temperature long before I rise and shine in the morning. I decided to go with an RTC chip produced by Maxim / Dallas Semiconductors – the DS3231M. This is a tiny 8-pin SOIC chip with onboard resonator that can communicate via I2C. As the display also uses I2C, the addition of this little chip on the I2C bus requires minimal effort. Of importance, this chip automatically performs carryover for seconds, minutes, hours, days, weeks, months, years, and century, and supports 24 and 12-hour timekeeping. Literally, you simply have to set it, and forget it. I was able to obtain four of these chips through the Dallas / Maxim sample program – plenty of chips to experiment with and place in the final prototype.

I’ve got both the display and RTC wired up to the Pro Mini – so far, everything is great!

To get the devices up and running together, I use the following skit:


#include <Wire.h>
#include <LCDNHDI2C.h>

//Custom Display Characters
const uint8_t custChar0[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; //Blank Char

uint8_t timeH, timeM, timeS;

LCDNHDI2C LCD = LCDNHDI2C(2, 16, 0x50>>1);
uint8_t lcdBuffer[2][17], lcdBufferCount;
unsigned long dispUpdateInterval; //Number of millis that must pass before the display is updated

void setup()
{
//Turn on I2C Bus
Wire.begin();
LCD.init();
LCD.setCharacter(0, custChar0);
LCD.setBacklight(0x0);
LCD.setContrast(0x2D);

Wire.beginTransmission(0xD0>>1);
Wire.write(0x00); //Point to register 0x00
Wire.write(0x00); //Set Seconds
Wire.write(0x28); //Set Minutes
Wire.write(1<<6|1<<5|0x11); //Set 12hr bit and PM bit with Hours
Wire.endTransmission(true);
}

void loop()
{
if ((millis() - dispUpdateInterval) > 50)
{
dispUpdateInterval = millis();
Wire.beginTransmission(0xD0>>1);
Wire.write(0x00);
Wire.endTransmission(false);
Wire.requestFrom(0xD0>>1, 3);
timeS = Wire.read();
timeM = Wire.read();
timeH = Wire.read();
//Line 0
LCD.setCursor(0,0);
if (1<<5 & timeH) { lcdBufferCount = sprintf((char*)lcdBuffer[0], "%X:%02Xp", timeH & 0x1F, timeM, timeS); } //If the PM bit is set, format the display string with a 'p'
else { lcdBufferCount = sprintf((char*)lcdBuffer[0], "%X:%02Xa", timeH & 0x1F, timeM, timeS); } //If the PM bit is not set, format the display string with an 'a'
Wire.beginTransmission(0x50<<1);
Wire.write(lcdBuffer[0],16);
Wire.endTransmission(0x00);
}
}

 

You will also need my revision of the Newhaven Display LCD library.