CyberQ II - Adding Arduino & WiFi Shield

Hello!

Looking into the feasibility for giving my BBQ Guru CyberQ II Wifi abilitites using a Arduino board & Wifi shield. Currently the CyberQ communicates with my laptop via USB (RS232 over USB I have read). It is not a network adapter compliant device, so simple solution is out. To get on network, I would have to leave my laptop outside with device and use USB over Network, use super long usb cable or wireless USB. I do not like any of those solutions.

So my question is can I use an Arduino board to communicate with this device via usb, grab the information an place onto the wifi shields web server and have a WiFi BBQ controller? I am a Arduino newbie, so going to start some small projects first. But this would be my goal project if feasible.

Some reference information on the device if anyone is interested.

http://www.thebbqguru.com/products/CyberQ-II-(No-fan%2C-no-adaptor).html
http://www.thebbqguru.com/pages/Manuals{47}Downloads.html

Thanks,
-=J

Is their protocol an open one? If so this could be relatively simple. If not it would take some work to try and decode what is going on. How many commands do you need? Just setpoint up/down, request setpoint, and request actual?

If that is all you need and the protocol is open, or simple to decode, I would think someone could hack it out in a day...

I am on good terms with the company (admin for their forum), so pretty sure I can gather some more information from them. Not like I am trying to ripoff their idea, just improve capabilities simply for my own use. If not, I was hoping something like a USB sniffer could yeild the info I needed.

Just found this in another forum:

The CyberQII uses the USB CDC ACM (universal serial bus communications device
class abstract control model) protocol, which emulates a virtual communications port on the PC.

Could probably live with a short list of commands, though every aspect of the device can be controlled via computer/usb (proportional band, deviation, cycle time, ramp, lid open adjust, alarms). But I can set those up via computer/usb and they are retained..not like they are adjusted every cook. The device controls up to two pits (with setpoint adjusts) and two food items (with alarm/ready setpoint adjusts)....so four adjustable setpoints, four temps read and two cycle time information from fans. Would also like to graph this information for trending.

Also about to buy a board and wondering if I should go with the Mega? Or is the Uno more than enough to handle this project?

Thanks,
-=J

Not sure what USB CDC ACM is, but if it just uses a usb to ttl serial, I would just listen in on it and see what information is going out over it. If you use XP there is a program called portmon that makes this very simple and free. If you use vista or 7, I was unable to find a free serial port sniffer when I looked a few months ago. If you know the baud rate you could set up an arduino to listen in on it and store it, for later analyzing. I would think since there are multiple grounds(cyberQ and your PC) that if you wanted real time results you would need something with two uarts (one to listen in and when to spit out the results).

I'm just a hobbyist. So that is my initial guesses on where I would start.

The Uno should be plenty for this. No sense in spending the extra money, especially if you are planning on leaving your final design on an arduino board. Plus I've ran into a few shield incompatibilities with my mega.

I've debating between a bbq guru and a Stoker for my BGE... The biggest thing the Stoker has going for it in my book is the ease in "hacking" it:) Of course now I think I may just try and build my own.

fiveohhh:
I've debating between a bbq guru and a Stoker for my BGE... The biggest thing the Stoker has going for it in my book is the ease in "hacking" it:) Of course now I think I may just try and build my own.

Hey, a fellow ceramic enthusiast. I have two komodokamado grills. Have owned almost any type you can think of (including pellet feeders) and ceramics are the best at doing it all....and doing it well.

Well, just so happens a friend is sending me a Stoker that he no longer uses. So I will have both to play with. But the Stoker seems to have it's own issues with no Wifi built in either and security leaks with the built in web server. So either way, seems like a Arduino board and Wifi to solve.

As soon as my CyberQ returns (decided to get the latest firmware for better PID control), I will try some port/usb sniffing to see what data/protocols come up. Going to order an Uno tonight to start playing.

Thanks,
-=J

fiveohhh:
Not sure what USB CDC ACM is,

Little more info on the protocol.
http://wiki.openmoko.org/wiki/CDC_ACM

And yeah, I run Win7 64bit....so have to do some research on sniffer. Though I have plenty of luck running programs in Win 7 64bit as x86 and/or with previous OS compatibility mode.

After more research, it appears I also need a USB Host Shield since the CyberQ II is a slave device along with the Arduino.

So just purchased one along with a LCD so I can learn more about trying to talk to CyberQ. Did get a chance to build most of the projects in the Getting Started With Arduino book with my Uno. Very cool stuff...wish I had heard about these a long time ago.

If anyone has any tips with the USB Host shield, I would love the advise.

-=J

Here you go, CyberQ II USB Connection source. Enjoy...

using System;
using System.IO.Ports;
using System.Threading;

namespace CyberQUSBConnection.USB
{
///


/// This class deals with:
/// 1. Opening/Closing USB COM-Port connection
/// 2. Send commands to the Hardware device
/// 3. Utility methods to read returned values
/// 4. Utility methods to do any miscellaneous operations
///

public class USBConnection
{
public static int HardwareUpdateAck = -1;
public static bool COMPortFound = false;
public static SerialPort Port = new SerialPort();
public static int SleepTime = 50;
public static int UpgradeSleepTime = 2;

public static void SendData(string usbinput)
{
// return if no connection
if (!Port.IsOpen)
{
return;
}
Port.Write(usbinput);
}

public static void SendData(char[] usbinput)
{
// return if no connection
if (!Port.IsOpen)
{
return;
}

Port.Write(usbinput, 0, usbinput.Length);
}

///


/// Get the latest data from the Hardware
///

public static bool GetData()
{
try
{
// return if no connection
if (!Port.IsOpen)
{
return true;
}

Port.Write("~[");
Thread.Sleep(SleepTime);
Port.Write("~A");
Thread.Sleep(SleepTime);
Port.Write("~B");
Thread.Sleep(SleepTime);
Port.Write("~C");
Thread.Sleep(SleepTime);
Port.Write("~D");
Thread.Sleep(SleepTime);
Port.Write("~E");
Thread.Sleep(SleepTime);
Port.Write("~F");
Thread.Sleep(SleepTime);
Port.Write("~G");
Thread.Sleep(SleepTime);
Port.Write("~H");
Thread.Sleep(SleepTime);
Port.Write("~I");
Thread.Sleep(SleepTime);
Port.Write("~J");
Thread.Sleep(SleepTime);
Port.Write("~K");
Thread.Sleep(SleepTime);
Port.Write("~L");
Thread.Sleep(SleepTime);
Port.Write("~M");
Thread.Sleep(SleepTime);
Port.Write("~N");
Thread.Sleep(SleepTime);
Port.Write("~O");
Thread.Sleep(SleepTime);
Port.Write("~P");
Thread.Sleep(SleepTime);
Port.Write("~Q");
Thread.Sleep(SleepTime);
Port.Write("~R");
Thread.Sleep(SleepTime);
Port.Write("~S");
Thread.Sleep(SleepTime);
Port.Write("~T");
Thread.Sleep(SleepTime);
Port.Write("~U");
Thread.Sleep(SleepTime);
Port.Write("~V");
Thread.Sleep(SleepTime);
Port.Write("~W");
Thread.Sleep(SleepTime);
Port.Write("~X");
Thread.Sleep(SleepTime);
Port.Write("~Y");
Thread.Sleep(SleepTime);
Port.Write("~Z");
Thread.Sleep(SleepTime);
}
catch (TimeoutException timeoutEx)
{
// ignore this guy
System.Diagnostics.Debug.WriteLine("GetData() TimeOutException: " + timeoutEx.Message);
System.Diagnostics.Debug.WriteLine("end time " + DateTime.Now.ToLongTimeString());
return false;
}
catch (Exception ex)
{
//throw ex;
System.Diagnostics.Debug.WriteLine("GetData() Exception: " + ex.Message);

return false;
}
return true;
}

///


/// Find the valid COM port number to connect to
///

private static bool FindCOMPort(decimal commPort)
{
// open the Port
if (!Port.IsOpen)
{
foreach (string comPortname in SerialPort.GetPortNames())
{
// Set SerialPort properties
Port.WriteTimeout = 200;
Port.ReadTimeout = 200;

//open port
if (commPort > 0)
{
Port.PortName = "COM" + commPort.ToString();
}
else
{
Port.PortName = comPortname;
}

// send test data
try
{
Port.Open();
Port.Write("~@");
Thread.Sleep(200);

if (COMPortFound)
{
return true;
}
else
{
// close and try the next one
Port.Close();
}
}
catch(Exception ex)
{
string error = ex.ToString();
}

//open port
if (commPort > 0)
{
break;
}
}
}
return COMPortFound;
}

private static bool FindCOMPortUpgrade(char[] testdata, decimal commPort)
{
// open the Port
if (!Port.IsOpen)
{
foreach (string comPortname in SerialPort.GetPortNames())
{
// Set SerialPort properties
Port.WriteTimeout = 200;
Port.ReadTimeout = 200;

//open port
if (commPort > 0)
{
Port.PortName = "COM" + commPort.ToString();
}
else
{
Port.PortName = comPortname;
}

// send test data
try
{
Port.Open();

// Send the first 100 characters and wait for the 19 message to come back
// Get the content from the web site or the file system
Port.Write(testdata, 0, 100);
Thread.Sleep(200);

if (USBConnection.HardwareUpdateAck == 19)
{
return true;
}
else
{
Port.Close();
}
}
catch (Exception ex)
{
string error = ex.ToString();
}

if (commPort > 0)
{
break;
}
}
}

return COMPortFound;
}

///


/// Figure out the proper Port and open the Port
///

///
public static bool OpenConnection(decimal commPort)
{
try
{
if (!FindCOMPort(commPort))
{
throw new Exception("Cannot find a valid COM Port");
}

// Set SerialPort properties
Port.WriteTimeout = 1000;
Port.ReadTimeout = 1000;

if (Port.IsOpen)
{
return true;
}

if (Port == null)
{
Port = new SerialPort();
if (!FindCOMPort(commPort))
{
throw new Exception("Cannot find a valid COM Port");
}
}

Port.Open();
return true;
}
catch
{
return false;
}
}

///


/// Close the connection
///

public static void CloseConnection()
{
try
{
if (Port.IsOpen)
{
COMPortFound = false;
Port.Close();
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.StackTrace);
}
}
}
}

Hey thanks. Any chance your working on something similar?

I finally recieved my USB host shield today. Have not even had time to solder in the pin headers yet.

-=J

I'm taking a different approach. My development is a ntier solution.

CyberQ II Device --> Application Server --> Web Service

With the above solution the consumers(in my local intranet) can be any client that can handle soap messages. ie Web Application, Microsoft Silverlight application, including Windows Phone etc.

I'm not a hardware guy, I'm a software engineer. So the above works for me.

Here is a little more source with the definition of the USB values...

private void timSettingEWaitTime_Tick(object sender, EventArgs e)
{
// and set respective values
string usbInput = string.Empty;
foreach (string key in Context.DirtyElements.Keys)
{
switch (key)
{
case "Pit1SetpointTrackBar":
usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Pit1SetpointTrackBar.Value)*2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~h" + usbInput);
}

break;
case "Pit2SetpointTrackBar":
usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Pit2SetpointTrackBar.Value)*2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~i" + usbInput);
}
break;
case "Pit1HoldTrackBar":
usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Pit1HoldTrackBar.Value) * 2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~j" + usbInput);
}
break;
case "Pit2HoldTrackBar":

usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Pit2HoldTrackBar.Value) * 2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~k" + usbInput);
}
break;
case "Food1SetpointTrackBar":
usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Food1SetpointTrackBar.Value) * 2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~l" + usbInput);
}
break;
case "Food2SetpointTrackBar":
usbInput = this.GetUSBValue(Context.GetFahrenheitTemp(this.Food2SetpointTrackBar.Value) * 2);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~m" + usbInput);
}
break;
case "CookTimer1TrackBar":
usbInput = this.GetTimerUSBValue(this.CookTimer1TrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~n" + usbInput);
}
break;
case "CookTimer2TrackBar":
usbInput = this.GetTimerUSBValue(this.CookTimer2TrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~o" + usbInput);
}
break;
case "TimeoutAction1TrackBar":
usbInput = this.GetTimeoutActionUSBValue(this.TimeoutAction1TrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~p" + usbInput);
}
break;
case "chkAlarm1":
usbInput = this.GetAlarmOnUSBValue(this.chkAlarm1.Checked==true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~p" + usbInput);
}
break;
case "chkRamp1":
usbInput = this.GetRampOnUSBValue(this.chkRamp1.Checked == true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~p" + usbInput);
}
break;
case "chkOpenLid1":
usbInput = this.GetOpenLidOnUSBValue(this.chkOpenLid1.Checked == true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~p" + usbInput);
}
break;
case "TimeoutAction2TrackBar":
usbInput = this.GetTimeoutActionUSBValue(this.TimeoutAction2TrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~q" + usbInput);
}
break;
case "chkAlarm2":
usbInput = this.GetAlarmOnUSBValue(this.chkAlarm2.Checked == true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~q" + usbInput);
}
break;
case "chkRamp2":
usbInput = this.GetRampOnUSBValue(this.chkRamp2.Checked == true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~q" + usbInput);
}

break;
case "chkOpenLid2":
usbInput = this.GetOpenLidOnUSBValue(this.chkOpenLid2.Checked == true ? 2 : 1);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~q" + usbInput);
}
break;
case "AlarmKeyBeepsTrackBar":
usbInput = this.GetUSBValue(this.AlarmKeyBeepsTrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~t" + usbInput);
}

break;
case "BackLightTrackBar":
usbInput = this.GetUSBValue(this.BackLightTrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~u" + usbInput);
}
break;
case "ProportionalBandTrackBar":
if (Context.TempCelsius)
{
usbInput = this.GetUSBValue( (this.ProportionalBandTrackBar.Value * 2 * 9) / 5 );
}
else
{
usbInput = this.GetUSBValue(this.ProportionalBandTrackBar.Value * 2);
}

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~v" + usbInput);
}
break;
case "RampOffSetTrackBar":
if (Context.TempCelsius)
{
usbInput = this.GetUSBValue((this.RampOffSetTrackBar.Value * 2 * 9) / 5);
}
else
{
usbInput = this.GetUSBValue(this.RampOffSetTrackBar.Value * 2);
}

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~x" + usbInput);
}
break;
case "AlarmDeviationTrackBar":
if (Context.TempCelsius)
{
usbInput = this.GetUSBValue((this.AlarmDeviationTrackBar.Value * 2 * 9)/5);
}
else
{
usbInput = this.GetUSBValue(this.AlarmDeviationTrackBar.Value * 2);
}

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~y" + usbInput);
}
break;
case "CycleTimeTrackBar":

usbInput = this.GetUSBValue(this.CycleTimeTrackBar.Value);

if (!usbInput.Equals(string.Empty))
{
USBConnection.SendData("~z" + usbInput);
}
break;
}
}
}

palmtreefrb:
I'm taking a different approach. My development is a ntier solution.

CyberQ II Device --> Application Server --> Web Service

With the above solution the consumers(in my local intranet) can be any client that can handle soap messages. ie Web Application, Microsoft Silverlight application, including Windows Phone etc.

I'm not a hardware guy, I'm a software engineer. So the above works for me.

Seems somewhat similar (at least to me)...as my plan is to use the arduino with wifi shield as a web server. Difference would be your leaving at least a laptop outside (or wireless USB) and I am leaving the arduino outside. As far as not being a hardware guy, that is what is great about the arduino solution...everything I have bought for the device is plug on. Seems everything is software which is what is killing me.

Thanks again!
-=J

Just for info on CyberQ:
I actually did do some research the other evening on the CyberQ microcontroller chip (datasheet below). Yes, I could not resist taking it apart and poking around. Interesting enough it does have a serial out on the chip (also USB). I had thought about not going the route of the Arduino USB host controller board and trying straight serial (since the base board can handle that). But that would mean tapping into the CyberQ main board bypassing the USB port and running new wires (they at least had the serial output already pinned to test points). But I was really going for a plugon type addon interface.

http://datasheet.octopart.com/PIC18F455 ... t-2911.pdf

Yep, very similar. It makes sense for me because I have my house wired up the wazoo and more PC's/hardware than I know what to do with.
Maybe we could collaborate in the future.

Oh, I like beer :slight_smile: ever try Pliny the Elder by Russian River Brewing?

palmtreefrb:
Yep, very similar. It makes sense for me because I have my house wired up the wazoo and more PC's/hardware than I know what to do with.
Maybe we could collaborate in the future.

Oh, I like beer :slight_smile: ever try Pliny the Elder by Russian River Brewing?

Never heard of that one. I love the fact that microbrews are popping up everywhere that I have never heard of before.....shows we are moving in the right direction! FYI, having a Stone Brewery Pale Ale as I type (my fav brewery even if it is on the wrong coast..hehe).

I can understand with stuff you already have. I have a bunch of equip hanging around myself. Hell, I already have a Stoker now too. I am mainly doing this as a learning experience. But collaboration sounds great!

-=J

Drunk_J:

palmtreefrb:
I'm taking a different approach. My development is a ntier solution.

CyberQ II Device --> Application Server --> Web Service

With the above solution the consumers(in my local intranet) can be any client that can handle soap messages. ie Web Application, Microsoft Silverlight application, including Windows Phone etc.

I'm not a hardware guy, I'm a software engineer. So the above works for me.

Seems somewhat similar (at least to me)...as my plan is to use the arduino with wifi shield as a web server. Difference would be your leaving at least a laptop outside (or wireless USB) and I am leaving the arduino outside. As far as not being a hardware guy, that is what is great about the arduino solution...everything I have bought for the device is plug on. Seems everything is software which is what is killing me.

Thanks again!
-=J

I took a similar but different approach with my CyberQ 2; I used a Broadcom-based Wifi router with USB (Asus WL-500gP) running Tomato USB to build a CyberQ2 data logger and web proxy. Basically, this means:

  • Install TomatoUSB
  • Install Optware
  • Make sure the USB serial device is enabled in the Tomato (Linux) stack.

I prototyped the CyberQ server using Python and CherryPy. For development, I used a bus-powered USB disk on the Wifi router but I suspect I could fit everything into internal flash if I wanted to.

Using the WRT-based stack on the Wifi router means I can easily configure it as an AP, bridge, or whatever is called-for in a particular situation. It also allows creating virtual APs, etc.

Since the project is now dead, I'm happy to make all of the source available to anyone interested. Most notably, I have a Python module (a few hundred lines of code) which exposes all of the CyberQ settings/status as Python properties. My web proxy was never more than a single line display of probe temperatures, I was happier with the CSV data log stored on the router's disk (available as a Windows share).

This way, I could leave the cheap commodity router ($50) outside and only turn on my notebook when I wanted to check status.

Dana K6JQ

danak6jq:
I took a similar but different approach with my CyberQ 2; I used a Broadcom-based Wifi router with USB (Asus WL-500gP) running Tomato USB to build a CyberQ2 data logger and web proxy.

yeah good idea, you could use proxies you can find some at proxy sites or add "https" before link. ;))

Here is a similar project - http://tvwbb.com/eve/forums/a/tpc/f/9270072103/m/7691098906

I actually have shelved my USB shield and the CyberQ for now. If I am going to put so much work into it, might as well make the whole damn controller. In the same forum as above, decided to build the HeaterMeter project instead.

-=J