Version 2 of my homebrew controller


 
Hi J,

I would also like to see the drawing of your version. Also if you would provide information about the web connection your using that would be great! Thanks for posting your results.

Fred
 
@Fred

I am using keepalive.

What I do is have the data url produce some special output that browsers can handle (JSON, Javascript Object Notation). Basically in your browser when you are on a webpage, that webpage can make calls to other urls in the background, but for security reasons it can only contact urls on the same domain (www.virtualbullet.com) that the page is on.

In our case we want to contact a local url (192.168.1.15, say), which is considered a different domain from the webpage the browser is on. There is a way to do this however, using something called JSONP. I won't get into the details (just google it if you want to know), but I use JSONP to hit the Controller url on a timer INSIDE the browser (no programs, no ping, all within the browser).

As for the sketch, I am talking about the Arduino sketch (c program). I don't have any new drawings, I just followed Bob's but added 4 more temperature sensors.
 
Hi J,
That's just what I needed. I'll let you know how my project goes as I move forward. Thanks again for your help.
icon_smile.gif


Fred
 
I have to say Thanks Bob. This has inspired me to dust of the old soldering iron and try to see if i can still program after switching out of Computer Science and doing an accounting degree (shudders).

I have a question for you though. How did you go about mounting the blower to your WSM? If possible can you show a picture of your setup?

Thanks
Andrew
 
Originally posted by Andrew Smith:
How did you go about mounting the blower to your WSM? If possible can you show a picture of your setup?

I don't have a picture handy, but I will try to describe it.

I bought a stainless steel dog food bowl with a diameter slightly larger than the vents on the bottom of the WSM. Drill or dremel a hole the size of the blower opening and mount the blower to that. Then run a long thin bolt through the bowl and through one of the vent holes and put a nut on it. When you tighten it it will pull the bowl up to the side of the smoker and the roundness will cause it all to seal off nicely.

Hope that makes sense, if not I will try to get outside and take a picture.
 
Has anyone thought of doing a custom board (shield) layout for the Arduino to share with the other interested folks here? The proto shield works alright if you're willing to spend the time and have decent soldering skills.

I personally like Bob's schematic as a starting point. So the big question would be, what other hardware features should this shield have?

Russ
 
Something to note is the new WiShield 2.0 is no longer compatible with Bob's original design. The 2.0 version of the WiShield now includes 16Mbit of flash storage accessible via SPI. D7 now serves as the SPI slave select, so it isn't available for use for the LCD. You can't use D8 because that's that interrupt line for the WiShield, leaving only D1/D2 (RX/TX).

I prefer having the serial pins open so they can be used for debugging, and won't conflict something when uploading a program. In this vein I've worked up a design that only uses 2 digital data pins for the LCD and adds a shift register IC ($0.75). This allows the WiShield to use the default interrupt pin (2), allows you to use the "WiFi Connected" LED (9), and have 2 digitals left over, perhaps for a second blower or running a servo to open a damper.

I've also added 3 buttons to the design hooked to one of the analog ports. This allows the user to adjust the setpoint at the device (via Up/Down/SET) rather than having to bust out a web browser.

So if you're designing a custom-made shield, it would be a good idea to add the 3 buttons and a 74LS164 shift register, with bonus points of connection another PWM to a second MOSFET to control a second blower.

j ostheim / Bob:
-- Do you just run your Arduino on the same 12V supply used to run the fan?
-- Also, how did you wrap your blower, is there a standard blower mounting bracket that I can buy then just built the piece to connect to my grill? I'm a programmer, not a metalshop...guy so the concept of making both pieces seems daunting.
 
Bryan that is some good work!

I am interested in seeing the details / source code for your changes and I'd love to incorporate them. I've had a plan to add buttons for manual setup for quite some time, but never got around to it.

For the blower bracket, all I did was bend a piece of sheet metal at a right angle and drill mounting holes in it - it's not all that daunting. I can guide you through it in more detail if you need it.

And yes, I run the blower off the same 12V wall wart that I run the Arduino from.
 
Thanks, Bob! I'll post the details once I'm done with my construction and I'm confident that everything is working properly. I'm still waiting on some parts to come in the mail.

As an overview, I'm using this 2 wire LCD method with this analog button reading idea.

Thanks for the info on how to mount the blower, I had all these of ideas of trying to learn to weld or something to make a box to hold it. Simple cutting and folding of sheet metal I can do!
 
I've been looking for a project for my arduino, and it looks like I've found it. Being the anal-retentive person I am, I was wondering if anyone has the eagle files for what they've developed so far?

My plan (so far) is to follow the basic plan, but instead of the suggested LCD, or a shift register use a serial enabled 16x2 LCD (sparkfun), which should free up some pins for other uses.
 
howdy! just thought i'd take a sec to say thanks to bob & everyone else who has contributed to this project! after stumbling onto this thread, i decided to build one of these for my dad. this is my first arduino / microcontroller build... a few speedbumps so far, but for the most part it has been pretty straightforward! first 2 runs were standalone. seemed to hold the temps pretty steady! i've since got the sparkfun serial LCD up and running, but am still working on deciphering the wifi portion of the code. i might have a few questions for you guys if i can't get it sorted.... anywho, here's a few picks of saturday's grub! thanx again!
-john c.

*edit* - chinese takeout enclosure is temporary!
icon_smile.gif


1.jpg

800px

2.jpg

800px

3.jpg

800px
 
The following info was taken from the Arduino web site.

"The power pins are as follows:

* VIN. The input voltage to the Arduino board when it's using an external power source (as opposed to 5 volts from the USB connection or other regulated power source). You can supply voltage through this pin, or, if supplying voltage via the power jack, access it through this pin."

If you power the board with a 12v power supply? The board will regulate the power down to the 5v it needs to run and you can use the vin pin for the 12v needed for the fan. Is my thinking flawed that you should be able to use the Ardunio's vin pin to power the fan?

Never mind. I think I answered my own question through Google search.
 
sweet! i've got the serial lcd working consistantly, wishield v2 is connecting to the router w/wpa2 enabled and creating a webpage with data, 192.168.1.xx/setup allows remote setting of temp threshold.

im still having problems with what i suspect is the keepalive portion of the code... the arduino continually resets shortly after connecting to the router. atm, im using a www.weather.gov address in the GETrequest (that was the only example i could find) but i suppose this isn't the proper way to do it. i have a windows box thats always on that i could use to serve the get request, just not sure how to go about making something available.... any hints or tips???

im getting really close to a fully functional controller! this physical computing stuff is really neat! just a bit much to absorb for someone who's never messed with C... kinda like trying to do a research paper in a foreign language.
icon_biggrin.gif

-jc
 
Hey John you care to share how you got the serial lcd working , Mine is in the mail and should be here in a few days along with a few other odds and ends.
 
Originally posted by john frank:
Originally posted by S ROY:
Hey John you care to share how you got the serial lcd working , Mine is in the mail and should be here in a few days along with a few other odds and ends.
haha, its kinda weird being asked for code when like 2 seconds ago i could have sworn i had no idea what's going on! lol!
icon_smile.gif


keep in mind im no programmer, so some of this may be way wrong.... i installed the SparkSoftLCD library to my Arduino Sketchbook Directory /libraries/SparkSoftLCD/ and modified the lcd instances in bob's sketch to match those in the example sketch provided with the library. *note - i moved the LCD TX pin to pin 3 & the blower to pin 4.

<pre class="ip-ubbcode-code-pre">/****************************************************
BBQ Controller
For information see http://hruska.us/tempmon

NOTES:

1) If USE_WISHIELD is defined, driver and server code is from:
http://asynclabs.com/wiki/inde...=WiShield_1.0_Driver
http://github.com/asynclabs/WiShield
Put all the files/directories under arduino/hardware/libraries/WiShield/ directory

in WiShield directory:
Edit apps-conf.h:
//Here we include the header file for the application(s) we use in our project.
//#define APP_WEBSERVER
//#define APP_WEBCLIENT
//#define APP_SOCKAPP
//#define APP_UDPAPP
#define APP_WISERVER

NOTE: The WiShield LED uses digital pin 9 to show that there is a
wifi connection. If an stardard 16x2 LCD is used, the only available pin for
blower PWM is pin 9. The LED jumper on the WiShield board should be
removed and the LED will not function.
If you are not using an LCD you can re-assign the blower PWM pin to 3, 5, or 6.

2) The WiShield by default uses INT0 (digital pin 2) for its interrupt. This code assumes that you
move the jumper on the WiShield from INT0 to D8 thus using D8 for the interrupt.
There is also a setup in the WiShield library file spi.h with the define:
//#define USE_DIG0_INTR // use digital pin 0
#define USE_DIG8_INTR // use digital pin 8

3) If USE_KEEPALIVE is defined, the IP address that you define in KEEPALIVE_ADDRESS will
be sent an http GET request every minute. If it returns data, all is well. If it
does not, the WiServer will be reset. Make sure the IP address you define here will
return valid data from an http GET request.


********** Edited for use with serial lcd sold by Sparkfun.com. ****************
Install the SparkSoftLCD library to the following directory: your arduino sketch folder /libraries/SparkSoftLCD/
The SparkSoftLCD library is available from:
http://openmoco.org/node/153
lcd = pin3
blower = pin4

*****************************************************/

#define USE_WISHIELD
// LCD transmit pin
#define LCD_TX 3
#define USE_KEEPALIVE

#define KEEPALIVE_ADDRESS 10, 1, 1, 50
#define BLOWER_PIN 4

#define DEFAULT_SETPOINT 225

//#include <avr/pgmspace.h>
#include <EEPROM.h>
#include "WiServer.h"
#include <SparkSoftLCD.h>

#define WIRELESS_MODE_INFRA 1
#define WIRELESS_MODE_ADHOC 2

//Wireless configuration parameters ----------------------------------------
unsigned char local_ip[] = { 10, 1, 2, 125 }; // IP address of WiShield
unsigned char gateway_ip[] = { 10, 1, 2, 1 }; // router or gateway IP address
unsigned char subnet_mask[] = { 255, 255, 255, 0 }; // subnet mask for the local network
unsigned char security_type = 1; // 0 - open; 1 - WEP; 2 - WPA; 3 - WPA2
// setup the wireless mode
// infrastructure - connect to AP
// adhoc - connect to another WiFi device
unsigned char wireless_mode = WIRELESS_MODE_INFRA;
unsigned char ssid_len;
unsigned char security_passphrase_len;

//NOTE: I have found that if I have an odd number of bytes of PROGMEM here then the board does not init
//at all. If you don't get a "Setup" message on the serial port, add a character to one of the
//PROGMEM fields and see if it helps......sigh

// WPA/WPA2 passphrase
const prog_char ssid[] PROGMEM = { "xxxx" }; // max 32 bytes
const prog_char security_passphrase[] PROGMEM = { "xxxxxxxxxxxxxxxxxxxx" }; // max 64 characters
// WEP 128-bit keys (modified to be 64 bit in library g2100.c func zg_write_wep_key()
prog_uchar wep_keys[] PROGMEM = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFF, 0x00, 0x00,0x00, 0x00, 0x00, 0x00,0x00,0x00, // Key 0
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00,0x00, // Key 1
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00,0x00, // Key 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00 }; // Key 3

prog_char html_open[] PROGMEM = "<html>";
prog_char html_close[] PROGMEM = "</html>";
prog_char html_form_close[] PROGMEM = "</form>";

prog_char html_settings_1[] PROGMEM =
"<form name=\"input\" action=\"setpoint\" method=\"get\">";
prog_char html_settings_2[] PROGMEM =
"Setpoint: <input type=\"text\" name=\"setpoint\" value=\"200\"><br>";
//prog_char html_settings_3[] PROGMEM = "P I D: <input type=\"text\" name=\"pid\"><br>";
prog_char html_settings_4[] PROGMEM = "<input type=\"Submit\">";
prog_char html_settings_5[] PROGMEM = "</form>";


//---------------------------------------------------------------------------

#ifdef LCD_TX 3

byte cur_bkl = 30;
boolean upd_disp = true;

SparkSoftLCD lcd = SparkSoftLCD(LCD_TX);
#endif // LCD_TX

#ifdef USE_KEEPALIVE && USE_WISHIELD
// IP address of a server you want to check connectivity to every minute
uint8 keepalive_ip[] = { KEEPALIVE_ADDRESS };
unsigned char keepalive_flag = 0;
GETrequest keepalive_get(keepalive_ip, 80, "keepalive-server", "/");
#endif //USE_KEEPALIVE


unsigned int current_millis_value = 0;
unsigned int previous_millis_value = 0;
unsigned int m = 0;
unsigned int minutes = 0;
unsigned int seconds = 0;
unsigned int hours = 0;
unsigned int food_temp = 0;
unsigned int pit_temp = 0;
unsigned int setpoint = DEFAULT_SETPOINT;
char wireless_stat='N';
int server_up = 0;
int server_resets = 0;

// Tuning constants for PID control.
// Set a constant to 0 to remove it's influence.

// So far, just using P=5 is looking good....
double PID_P = 5;
double PID_I = 0.02;
double PID_D = 0;
double PID_BIAS = 3;

// For integral, determine how often to update integral sum
// Integral is used to null out offset, so can be independent of offset size
int PID_I_FREQ = 6;

unsigned char fan_speed;

// EEPROM config data
typedef struct configData {
unsigned int configured;
unsigned int targetTemp;
};

configData config;

#ifdef USE_KEEPALIVE && USE_WISHIELD
// Function to handle data from the server
void processData(char* data, int len) {
static int state = 0;
char line[40];
char *ptr;

if (state == 0) {
// just grab first buffer, dump the rest
//sprintf(line, "Got %d bytes from processData\n", len);
//Serial.print(line);
//Serial.println(data);
state = 1;
// If we got anything valid, reset keepalive flag
if(len > 0) {
Serial.println("keepalive get received");
keepalive_flag = 0;
}
}

// When get is complete or fails, we get called with len=0. Reset state.
if (len == 0) {
state = 0;
}

}
#endif // USE_KEEPALIVE

void setup() {

Serial.begin(57600);

//Get stored setpoint from EEPROM. It is saved there whenver the web interface updates it
//If it has never been initialized, store the default setpoint into it and set it to
//initialized for next time.
readConfig();
if (config.configured != 0x1234) {
config.configured = 0x1234;
config.targetTemp = DEFAULT_SETPOINT;
writeConfig();
} else {
setpoint = config.targetTemp;
}

pinMode(BLOWER_PIN, OUTPUT);

#ifdef USE_KEEPALIVE && USE_WISHIELD
// Have the processData function called when data is returned by the server
keepalive_get.setReturnFunc(processData);
#endif //USE_KEEPALIVE

#ifdef LCD_TX
pinMode(LCD_TX, OUTPUT);
lcd.begin(9600);

lcd.clear();
// hidden cursor
lcd.cursor(0);
#endif //LCD_TX

}

void loop() {
// Update clock time, run any pending timer routines,
// and do web server processing

update_time();

#ifdef USE_WISHIELD
if(!server_up) {
server_up = WiServer.async_init(sendMyPage, 0);
//WiServer.enableVerboseMode(true);
} else {
//WiServer.enableVerboseMode(true);
WiServer.server_task();
}
#endif // USE_WISHIELD
}


void readConfig() {

int i = sizeof(configData) - 1;
unsigned char * p = i + (unsigned char *)&config;
while (i >=0) {
*(p--) = EEPROM.read(i--);
}
}

void writeConfig() {

int i = sizeof(configData) - 1;
unsigned char * p = i + (unsigned char *)&config;
while (i >=0) {
EEPROM.write(i--, *(p--));
}
}

#ifdef USE_WISHIELD
void web_print_stats() {
char line[80];
double fan_pctg;

fan_pctg = (double) fan_speed / (double) 255;
sprintf(line, "<h2>Setpoint: %d</h2>", setpoint);
WiServer.print(line);
sprintf(line, "<h2>Pit temp : %d</h2>", pit_temp);
WiServer.print(line);
sprintf(line, "<h2>Fan speed: %d%%</h2>", (int) (100 * ((double) fan_speed
/ (double) 255)));
WiServer.print(line);
sprintf(line, "<h2>Server restarts: %d</h2>", server_resets);
WiServer.print(line);
sprintf(line, "<h2>Elapsed time: %2.2d:%2.2d:%2.2d</h2>", hours, minutes,
seconds);
WiServer.print(line);

}
// This is our page serving function that generates web pages
boolean sendMyPage(char* URL) {
char line[80];

// Check if the requested URL matches "/" and if so give generic info page

if (strcmp(URL, "/") == 0) {
WiServer.print_P(html_open);
web_print_stats();
WiServer.print_P(html_close);

return true;
}

// If URL is "/data" then output one line compact data string for logging
if (strcmp(URL, "/data") == 0) {
WiServer.print_P(html_open);
sprintf(line, ",%d,%d,%d,%d,%2.2d:%2.2d:%2.2d,\n", pit_temp, food_temp,
setpoint, fan_speed * 100 / 255, hours, minutes, seconds);
WiServer.print(line);
WiServer.print_P(html_close);

return true;
}
// If URL is "/reset" then reset web server
if (strcmp(URL, "/reset") == 0) {
WiServer.init(sendMyPage);

return true;
}

// Present a form for setting variables via web page....should have a password....
if (strcmp(URL, "/setup") == 0) {
WiServer.print_P(html_open);
WiServer.print_P(html_settings_1);
WiServer.print_P(html_settings_2);
// WiServer.print_P(html_settings_3);
WiServer.print_P(html_settings_4);
WiServer.print_P(html_settings_5);
WiServer.print_P(html_close);
return true;
}

// This is the URL that is returned from the "/setup" form. Set the variables.
if (strncmp(URL, "/setpoint", 8) == 0) {

sscanf(URL, "/setpoint?setpoint=%d", &setpoint);
config.targetTemp = setpoint;
writeConfig();
WiServer.print_P(html_open);
web_print_stats();
WiServer.print_P(html_close);

return true;
}

// URL not found
WiServer.print_P(html_open);
WiServer.print("ERROR: Improperly formatted URL<p>");
WiServer.print(URL);
WiServer.print_P(html_close);
return true;
}
#endif // USE_WISHIELD

void hours_tick() {

}

void minutes_tick() {
static unsigned char counter = 0;

#ifdef USE_WISHIELD
if (WiServer.connection_up()) {
wireless_stat = 'W';
} else {
// It's down...try to restart it //
wireless_stat = 'N';
server_up = WiServer.async_init(sendMyPage, 1);
server_resets++;
//WiServer.enableVerboseMode(true);
}
#ifdef USE_KEEPALIVE && USER_WISHIELD
if(keepalive_flag) {
// It has been one minute and no response - reset WiServer
Serial.println("No response - resetting WiServer");
server_up = WiServer.async_init(sendMyPage, 1);
keepalive_flag = 0;
server_resets++;
} else {
// Send request to the keepalive ip and make sure we can still talk
Serial.println("Sending keepalive GET");
keepalive_flag = 1;
keepalive_get.submit();
}
#endif // USE_KEEPALIVE
#endif // USE_WISHIELD

if (counter++ == 5) {
// 5 minute sanity check
counter = 0;

#ifdef USE_WISHIELD
if (WiServer.connection_up()) {
wireless_stat = 'W';
} else {
// It's down...try to restart it //
wireless_stat = 'N';
server_up = WiServer.async_init(sendMyPage, 1);
server_resets++;
//WiServer.enableVerboseMode(true);
}


#endif // USE_WISHIELD
//sanity_check = 1;
}
Serial.println("Minutes tick");
}
// Run this every second. Inside it could also have static counters to run things on
// other multiples of seconds.
void seconds_tick() {
char line[60];

#ifdef USE_WISHIELD
if (WiServer.connection_up()) {
wireless_stat = 'W';
} else {
wireless_stat = 'N';
}
#endif // USE_WISHIELD
pit_temp = thermister_temp(analogRead(5));
food_temp = thermister_temp(analogRead(4));
fan_speed = DoControlAlgorithm(setpoint, pit_temp);
analogWrite(BLOWER_PIN, fan_speed);

sprintf(line, "%2.2d:%2.2d:%2.2d Pit=%3d Food=%3d Setpoint=%d Blower=%d %c ", hours, minutes, seconds, pit_temp, food_temp, setpoint, fan_speed*100/255, wireless_stat);
Serial.println(line);

#ifdef LCD_TX
lcd.clear();
lcd.cursor(0);
sprintf(line, "%2.2d:%2.2d %3d%c/%3d%c", hours, minutes, pit_temp, 0xDF,
setpoint, 0xDF);
lcd.print(line);
lcd.cursorTo(2,1);
sprintf(line, "M=%3d%c B=%2.2d%% %c", food_temp, 0xDF, fan_speed * 100 / 255, wireless_stat);
lcd.print(line);
#endif // LCD_TX
}

void update_time() {
static unsigned char last_seconds = 0;
static unsigned char last_minutes = 0;
static unsigned char last_hours = 0;

current_millis_value = millis();
m += current_millis_value - previous_millis_value;
seconds += m / 1000;
minutes += seconds / 60;
hours += minutes / 60;
if (seconds > last_seconds) {
last_seconds = seconds % 60;
seconds_tick();
}
if (minutes > last_minutes) {
last_minutes = minutes % 60;
minutes_tick();
}
if (hours > last_hours) {
last_hours = hours % 24;
hours_tick();
}
m = m % 1000;
seconds = seconds % 60;
minutes = minutes % 60;
hours = hours % 24;
previous_millis_value = current_millis_value;
}


unsigned char DoControlAlgorithm(int setPoint, int currentTemp) {
unsigned char fanSpeed = 0;
// state we need to save
static float integralSum = 0, prevError = 0;
static unsigned char integralCount = 0;

float error, proportional, integral = 0;
float derivative, control, prelimitcontrol;

// calculate the current error
error = setPoint - currentTemp;

// proportional term
proportional = PID_P * error;

// derivative
derivative = error - prevError;
derivative = derivative * PID_D;
prevError = error;

// control value is % (0 - 100)
control = PID_BIAS + proportional + derivative;

prelimitcontrol = control;
// integral term. see if it's time to do an integral update (and
// that integral term isn't 0)
if (++integralCount >= PID_I_FREQ) {
integralCount = 0;

// integral accumulation - include "anti windup" test.
// Don't change the integral being accumulated if the control value is
// already at 100% and the integral error is positive (which would increase
// the control value even more), and don't change the integral sum if
// the control value is already at 0% and the integral error is negative
// (which would decrease the control value even more)
// Since we've already added it in, remove it here if necessary

if (error >= 0) {
integral = PID_I * error;
if (control + integralSum < 100) {
// experiment
integralSum += integral;
}
} else {
// A possibility to try here....if error is negative, increase the rate
// that we slow the fan down by multiplying PID_I
// i.e. integral = PID_I*2 * error;
integral = PID_I * error;
if (control + integralSum > 0) {
integralSum += integral;
}
}

}
control += integralSum;

// limit control
if (control > 100)
control = 100;
else if (control < 0)
control = 0;

// convert to PWM setting ( 0 - 255), (50 is to round instead of truncate)
fanSpeed = ((control * 255) + 50) / 100;

return fanSpeed;
}

int thermister_temp(int aval) {
double R, T;

// These were calculated from the thermister data sheet
// A = 2.3067434E-4;
// B = 2.3696596E-4;
// C = 1.2636414E-7;
//
// This is the value of the other half of the voltage divider
// Rknown = 22200;

// Do the log once so as not to do it 4 times in the equation
// R = log(((1024/(double)aval)-1)*(double)22200);
R = log((1 / ((1024 / (double) aval) - 1)) * (double) 22200);
//lcd.print("A="); lcd.print(aval); lcd.print(" R="); lcd.print(R);
// Compute degrees C
T = (1 / ((2.3067434E-4) + (2.3696596E-4) * R + (1.2636414E-7) * R * R * R)) - 273.25;
// return degrees F
return ((int) ((T * 9.0) / 5.0 + 32.0));
}

void CelsiusToFarenheit(float const tCel, float &tFar) {
tFar = tCel * 1.8 + 32;
}
</pre>
 
Thanks, john frank. I think we are both in the same boat. I appreciate you sharing. Maybe between the two of us we can get it functioning properly.
 
Do I need C++ to code compile or can I code and compile in Arduino. I am not having any look with the code in Arduino IDE V.18
 
Originally posted by S ROY:
Do I need C++ to code compile or can I code and compile in Arduino. I am not having any look with the code in Arduino IDE V.18
hmm... i just copied & pasted into arduino ide 1.8 and it compiled for me. do you have all of your dependent libraries in the right places?

have your tried commenting out the wireless or keepalive to see if it compiles? cheers!
-sj
 
OK I commented out the following:
#define LCD_TX 1
#define USE_KEEPALIVE
#define KEEPALIVE_ADDRESS 38, 102, 136, 104
#include <SparkSoftLCD.h>

and it finally compiled. I am going to work on solving these last to problems one at a time. I Will have to wait until LCD shows up to tackle it. I am going to start with the USE_KEEPALIVE. IS someone willing to explain the USE_KEEPALIVE part of the code to me. On the good side It did compile with the above mentioned changes And I got the WiShield working.
icon_biggrin.gif
 

 

Back
Top