Showing posts with label food. Show all posts
Showing posts with label food. Show all posts

Monday, February 4, 2013

Slow cook on the cheap using Arduino 温泉蛋

If you search for "diy sous vide" on google, you get a lot of results stating how cheap they managed to get their sous vide setup vs commercial home use version costing a few hundred US dollars at least. Ever since dad saw this proto-typing electronic board called Arduino 1 year ago, he's been saying he would set one up. Finally got round to it last week and cooked onsen eggs with the setup. For details about how to cook eggs to perfection, just google "egg sous vide" for a myriad of detail discussions on the optimal temperature and timing for cooking egg. For dad's setup, he used 64-65C temperature and about 60 minutes, it all depends on the consistency of the egg yolk you want.

Yummy!!!

Onsen egg just cooked with a few drops of prime soy sauce

Arduino with LCD shield with 2 pins connected, a relay controlling on/off of the heating element and a water-proof temperature sensor based on DS18B20

Excluding the stainless steel pot, the total cost of the electronics and heating element is less than US$20 and this isn't even optimised with dedicated PCBs for micro-controllers.
The code can be modified to include cooking time, total energy consumed etc at no extra costs.

If you by chance come to this blog on the back of this, do let us know by leaving a comment:)

Below are the codes for the controls, which are based on 2 main sources of libraries:
LCD4Bit_mod.h to control LCD Keypad shield
http://www.dfrobot.com/wiki/index.php?title=Arduino_LCD_KeyPad_Shield_(SKU:_DFR0009)
Events.h etc from M Romani
http://arduino.cc/forum/index.php/topic,37650.0.html


#include <Events.h>
#include <EventQueue.h>
#include <EventDispatcher.h>

#include <LCD4Bit_mod.h>
#include <stdio.h>

//create object to control an LCD.  
//number of lines in display=1
LCD4Bit_mod lcd = LCD4Bit_mod(2); 

int getCurrentTemp(char *temp);
void convIntString(char *temp, int tempnum);

//Analog values of key presses
int  adc_key_val[5] ={30, 150, 360, 535, 760 };
char temp_string[10];


#define NUM_KEYS    5
#define KEY_RIGHT   0
#define KEY_UP      1
#define KEY_DOWN    2
#define KEY_LEFT    3
#define KEY_SELECT  4

#define TEMP_PIN 3     //DS18B20 data pin

#define RELAY_PIN 11     //relay pin this is the pin next to pin3



int adc_key_in;
int key=-1;
int oldkey=-1;
int temp_target=60;    //target temperature of the sous vide bath
int counter=1;

// the event queue
EventQueue q;

// the event dispatcher
EventDispatcher disp(&q);

// use this analog channel
#define AN_CHAN 0

// generate an event when the analog
// channel value changes this much
// increase value for noisy sources
//#define AN_DELTA 5

// time event handler
void timeHandler(int event, int param) {
  
    int curr_temp;
    curr_temp=getCurrentTemp(temp_string); 
    //call getCurrentTemp will return current temperature both in integer and string
    lcd.cursorTo(2, 0);  
    lcd.printIn(temp_string); 
    
    convIntString(temp_string, temp_target);
    lcd.cursorTo(1,5);
    lcd.printIn(temp_string);
    
    if (curr_temp < temp_target) {
      digitalWrite(RELAY_PIN, HIGH);
      lcd.cursorTo(1, 7);  
      lcd.printIn("HeaterOn "); 
    }
      
    else {
      digitalWrite(RELAY_PIN, LOW);
      lcd.cursorTo(1, 7);  
      lcd.printIn("HeaterOff"); 
    }  
        
}

// analog event handler
void analogkeyHandler(int event, int param) {
  lcd.clear();
  
  switch (param) {
    
    case KEY_SELECT: //Not Implemented
    lcd.cursorTo(1, 0); 
    lcd.printIn("SELECT NA");
    break;

    case KEY_RIGHT: //Not Implemented
    lcd.cursorTo(1, 0);  
    lcd.printIn("Right NA");
    break;
    
    case KEY_UP:        // Increase target temperature by 1C
    lcd.cursorTo(1, 0);  
    lcd.printIn("Up ");
    if (temp_target < 84)
      temp_target = temp_target + 1;
    break;
    
    case KEY_DOWN:      // Decrease target temperature by 1C
    lcd.cursorTo(1, 0);  
    lcd.printIn("Down ");
    if (temp_target > 40)
      temp_target = temp_target - 1;
    break;
    
    case KEY_LEFT: //Not Implemented
    lcd.cursorTo(1, 0);  
    lcd.printIn("Left NA");
    break;

  }
}

// this function generates an EV_TIME event
// each 1000 ms
// If you don't want the relay to jump back and forth too often
// at around the target temperature
// you can change the timing intervals

void timeManager() {
    static unsigned long prevMillis = 0;
    unsigned long currMillis;

    currMillis = millis();
    if (currMillis - prevMillis >= 1000) {
        prevMillis = currMillis;
        q.enqueueEvent(Events::EV_TIME, 0);    // param is not used here
    }
}

// this function generates an EV_ANALOG event
// whenever the analog channel AN_CHAN changes
void analogkeyManager() {

    adc_key_in = analogRead(AN_CHAN);  // read the value from AN_CHAN
    key = get_key(adc_key_in);    // convert into key press

    if (key != oldkey)         // if keypress is detected
    {
      delay(50);  // wait for debounce time
      adc_key_in = analogRead(AN_CHAN);  // read the value from AN_CHAN **AGAIN**
      key = get_key(adc_key_in);          // convert into key press
      if (key != oldkey)    
      {   
        oldkey = key;
        if (key >=0) {
          q.enqueueEvent(Events::EV_ANALOG0, key);    // use param to pass key value to event handler
        }
      }
    }
}

// Convert ADC value to key number
int get_key(unsigned int input)
{
 int k;
    
 for (k = 0; k < NUM_KEYS; k++)
 {
  if (input < adc_key_val[k])
  {
           
    return k;
        }
 }
    
    if (k >= NUM_KEYS)
        k = -1;     // No valid key pressed
    
    return k;
}

void lcdprint_interval (char *minsec, int interval)
{
  char temp_string[10];
  lcd.cursorTo(2, 9);  
  lcd.printIn(minsec);
  convIntString(temp_string, interval);
  lcd.cursorTo(2, 5);  
  lcd.printIn(temp_string);
  Serial.println(interval);

}

// routine for getting temperature
// standard for the OneWire DS18B20

void OneWireReset(int Pin) // reset.  Should improve to act as a presence pulse
{
     digitalWrite(Pin, LOW);
     pinMode(Pin, OUTPUT); // bring low for 500 us
     delayMicroseconds(500);
     pinMode(Pin, INPUT);
     delayMicroseconds(500);
}

void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
   byte n;

   for(n=8; n!=0; n--)
   {
      if ((d & 0x01) == 1)  // test least sig bit
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(5);
         pinMode(Pin, INPUT);
         delayMicroseconds(60);
      }
      else
      {
         digitalWrite(Pin, LOW);
         pinMode(Pin, OUTPUT);
         delayMicroseconds(60);
         pinMode(Pin, INPUT);
      }

      d=d>>1; // now the next bit is in the least sig bit position.
   }
   
}

byte OneWireInByte(int Pin) // read byte, least sig byte first
{
    byte d, n, b;

    for (n=0; n<8; n++)
    {
        digitalWrite(Pin, LOW);
        pinMode(Pin, OUTPUT);
        delayMicroseconds(5);
        pinMode(Pin, INPUT);
        delayMicroseconds(5);
        b = digitalRead(Pin);
        delayMicroseconds(50);
        d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
    }
    return(d);
}


int getCurrentTemp(char *temp)
{  
  int HighByte, LowByte, TReading, Tc_100, sign, whole, fract;

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0x44); // perform temperature conversion, strong pullup for one sec

  OneWireReset(TEMP_PIN);
  OneWireOutByte(TEMP_PIN, 0xcc);
  OneWireOutByte(TEMP_PIN, 0xbe);

  LowByte = OneWireInByte(TEMP_PIN);
  HighByte = OneWireInByte(TEMP_PIN);
  TReading = (HighByte << 8) + LowByte;
  sign = TReading & 0x8000;  // test most sig bit
  if (sign) // negative
  {
    TReading = (TReading ^ 0xffff) + 1; // 2's comp
  }
  Tc_100 = (6 * TReading) + TReading / 4;    // multiply by (100 * 0.0625) or 6.25

  whole = Tc_100 / 100;  // separate off the whole and fractional portions
  fract = Tc_100 % 100;

/*
 if(sign) temp[0]='-';
 else    temp[0]='+';
 
 temp[1]= whole%100+'0';
 temp[2]= (whole-100*temp[1])%10 +'0' ;
 temp[3]= whole-100*temp[1]-10*temp[2] +'0';
 
 temp[4]='.';
 temp[5]=fract%10 +'0';
 temp[6]=fract-temp[5]*10 +'0';
 
 temp[7] = '\0';
*/

 sprintf(temp, "%c%3d%c%2d", (sign==0)?'+':'-', whole, '.', fract);
        return whole;
 
} 
// End of Getting temperature routine


void convIntString(char *temp, int tempnum)
{  
 sprintf(temp, "%2d", tempnum); 
} 


// program setup
void setup() {
   // Serial.begin(115200); // Serial Port can be used for future debugging
   // initialize DS18B20 datapin
    digitalWrite(TEMP_PIN, LOW);
    pinMode(TEMP_PIN, INPUT);      // sets the digital pin as input (logic 1)
    
    pinMode(RELAY_PIN, OUTPUT);    // sets Relay pin to output
    lcd.init();
  //optionally, now set up our application-specific display settings, 
  //overriding whatever the lcd did in lcd.init()
  //lcd.commandWrite(0x0F);//cursor on, display on, blink on.  (nasty!)
    lcd.clear();

    disp.addEventListener(Events::EV_TIME, timeHandler);
    disp.addEventListener(Events::EV_ANALOG0, analogkeyHandler);
}

// loop
void loop() {
    // call the event generating functions
    timeManager();
    analogkeyManager();

    // get events from the queue and call the
    // registered function(s)
    disp.run();
}
 

Paris come to Hong Kong - Eric Kayser and Laduree

Hong Kong must be an attractive place for foreign brands to do business. You don't need to look far to see people queueing up to go into flagship stores of Chanel, Louis Vuitton etc. You also get famous patisseries and bakeries from Paris setting up shops in Hong Kong. Maison du Chocolat, Jean Paul Hevin have been here for quite some time. Now we have two additions in TST.

Laduree - the name synonymous to macarons, has opened a shop in Harbour City in TST. Modelled in the exact same fashion as their Paris shops, the shop sits directly opposite a Prince Jewellery and Watches store. At 30 dollars a pop, you get to compare macarons made with 150 years of tradition vs all the pretenders to the crown.



Eric Kayser - a famous bakery chain had its grand opening in Jan, also in Harbour City.










Eaten fresh, Eric Kayser's bread are soft and tasty. Try its olive bread if you get a chance. Lunch menu is good value. The savoury dishes are cooked to a high standard and you get a basket of its bread selection. The optional desserts are great value for HK$20 additional but guess they can be better.

We wait for its Happy Valley branch to open in April, then we might get to try the crumbs!!

Saturday, March 17, 2012

Special Treats - Lily's Kitchen Proper Dog Treats

If there's anything which guarantees our attention, it's the word "Treat!!". And we are getting something special tonight.


Thanks auntie R for the lovely gift. Tasting report to follow.

Update -
First night tasting - we ate the Blissful Bedtime Biscuits and went straight into a coma until the next morning.  Mum thought it was some secret ingredients in the biscuits, chamomile perhaps, which put us to slumber. But then we had a whiff of 18 year Macallan Whiskey before we ate the biscuits, so not sure which was more powerful.
Second night tasting - we were clamoring for the biscuits and we had two each. Scottie couldn't get to sleep after, still too hungry from the long walk in the afternoon. No whiskey no sleep. But they were delicious nonetheless.

Monday, February 20, 2012

Worst menu item translation

I bet you don't look closely at your holiday photos. With terabytes of data on your hard drive, it's perhaps understandable. Once in a blue moon, you might overlook little gems in the far corner of your photos. Check out the menu below:



Guess you wouldn't want to eat this piece of sushi upon seeing this translation. That fish will give you malignant smallpox!! The trouble is even a Japanese speaker may not know the exact menu item.

This translation suffers from a multitude of sins.

First, "tlatfish" is in fact flatfish with a typo and they are better known as flounders.

But more importantly, the first two Kanjis, 松皮, which can be translated as an abbreviated term of a malignant form of smallpox, should not be translated in isolation here. "松皮かれい"is in fact barfin flounder and considered the king of flounders rarely caught around the Hokkaido and Akita.

And now with the proper translation, you might be more inclined to try out this piece of sushi!!

Friday, February 17, 2012

Hokkaido 2012 - Eating Out in Sapporo & Furano グルメ 札幌 富良野

As you probably know by now, vacation trip for mum and dad isn't quite complete without going out of their way to search for food. So lets just see what they had in Hokkaido.

Sashimi beef rice bowl (sukiyaki beef set behind)

Sashimi beef rice bowl 和牛刺身丼 from Kumagera くまげら in Furano. Slices of  locally raised beef over a bowl of hot rice topped with a small dollop of wasabi, this is the signature dish of this famous restaurant. Walked in from the freezing cold of below -10C, one bowl may not be quite enough. The melt-in-your-mouth beef is perfect complement to the slightly sweet rice.

You can develop a huge appetite after skiing from dawn till dusk. You might associate dull and tasteless offering with ski resorts' restaurants, but mum and dad just couldn't say enough good things about the restaurants within the New Furano Prince Hotel. You can see some of food they had there.



Furano beef steak rice bowl
Fried Tokachi Pork Cutlet rice bowl


炭焼処きたぐに - Sumiyaki Dokoro Kitaguni serves local produce in Izakaya style


Roast pork loin from upper Furano 上富良野ポークロース焼き



Roast Taraba Crab claws


Dim sum buffet lunch, a firm favorite with a lot of Furano locals
There are plenty of restaurants to sample in Hokkaido and if a restaurant is mentioned in one of the Hong Kong guidebooks then you shouldn't be surprised to see an even longer queue of people with quite a few Hongkongers waiting in line. That was definitely the case with Nemuro Hana Sushi in JR Stellar Place building.



Creamy swiss roll with soft ice cream inside Shiroi Koibito Coffee Shop


Botan ebi from Gourmet Tei in Sapporo Fish Market ボタン海老−北のグルメ亭


Mix seafood Chirashi again from the Sapporo Fish Market


A massive bowl of Ramen from Ichiryuan near Sapporo JR station - 一粒庵

Wednesday, July 6, 2011

Photos we like - Part 2

Big lychees at the front from Hainan Island looked delicious but the Hong Kong grown small ones were the sweet ones. Not sure if they apply to other things as well?!

Sicilian eggplants - sound classy and continental. But these are bought in North Point market and grown in Thailand!! ゼブラなす, its Japanese name comes from its other common name, Zebra eggplant.

This red-vented bulbul was heading for its last session of feeding the baby bird before the whole family left their nest when young bulbul finally completed its flying lesson. It might look cute but it is included among the world most invasive alien species!! We know coz these are the birdies who ate our peaches.

A clear night in Hong Kong, when everyone was watching TVB......

A tree taller than IFC came out from nowhere,

Thursday, June 23, 2011

Kyushu 九州 Trip - Can't Stop Dreaming about the Food!!

The slab of Kumamoto (熊本) beef served to all the diners in Nonohana (野の花) in Kurokawa(黒川) that evening.

Shabu shabu in Zen(禅), Miyazaki(宮崎)
宮崎県宮崎市中央通1番19号

Teppanyaki in Imari (伊万里), Imari Beef on the right

Shabu shabu in Saga (佐賀)

Looks like beef, taste almost like beef but they are Kumamoto specialties, Horse sashimi (馬刺).

Superb value Sushi lunch at Hyoutan Sushi (ひょうたん寿司)
福岡県福岡市中央区天神2-10-20
The abalone (アワビ) is so fresh that it crawls away from the rice ball!!

Finest quality fatty tuna belly (極上大トロ)
 Hyoutan Sushi (ひょうたん寿司)
福岡県福岡市中央区天神2-10-20

Too hungry to worry about taking pictures. The chicken was heavenly though!!
 Yakitori in Ichiro(一郎), Miyazaki(宮崎)
宮崎県宮崎市中央通2-13

Black curry croquette in Kurokawa (黒川). The white one was good but the black one was really special.

Onsen egg. If you can get a constant 65C hot water bath going, you can also get something like this. Sous vide cooking.

Lobster Miso soup (伊勢エビみそ汁) from along the coast of Aoshima (青島)

Wiggling legs of the lobster, probably not for the faint-hearted

Uni picked up along the coastline of Aoshima (青島)

Wednesday, August 25, 2010

Recent photos

Art Exhibition in Time Square

Home made lotus-leaf rice 荷葉飯

Pity!! We couldn't capture the smell!!

Speeding through Admiralty

Ice cream making class in Grand Hyatt - terribly organized

Home made Osmanthus Jelly 桂花

All the ingredients

Another Citysuper Cooking Competition - Le Creuset Theme

Pan-fried Scallops, Beef-stew with Fried Potatoes and Berry Crumble