In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from DS18B20.h:2,
from DS18B20.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from LiquidCrystal/LiquidCrystal.cpp:1:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:30:0,
from OneWire/OneWire.h:8,
from OneWire/OneWire.cpp:131:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from OneWire/OneWire.cpp:131:0:
OneWire/OneWire.h:31:0: warning: "FALSE" redefined [enabled by default]
#define FALSE 0
^
In file included from ../../core-common-lib/CC3000_Host_Driver/cc3000_common.h:38:0,
from ../../core-common-lib/SPARK_Firmware_Driver/inc/hw_config.h:35,
from ../inc/main.h:37,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:34,
from OneWire/OneWire.h:8,
from OneWire/OneWire.cpp:131:
../../core-common-lib/CC3000_Host_Driver/data_types.h:53:0: note: this is the location of the previous definition
#define FALSE (0)
^
In file included from OneWire/OneWire.cpp:131:0:
OneWire/OneWire.h:32:0: warning: "TRUE" redefined [enabled by default]
#define TRUE 1
^
In file included from ../../core-common-lib/CC3000_Host_Driver/cc3000_common.h:38:0,
from ../../core-common-lib/SPARK_Firmware_Driver/inc/hw_config.h:35,
from ../inc/main.h:37,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:34,
from OneWire/OneWire.h:8,
from OneWire/OneWire.cpp:131:
../../core-common-lib/CC3000_Host_Driver/data_types.h:57:0: note: this is the location of the previous definition
#define TRUE (!FALSE)
^
In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from OneWire.cpp:4:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ../inc/spark_wiring.h:30:0,
from ../inc/application.h:29,
from ds18b20_w_lcd.cpp:2:
../../core-common-lib/SPARK_Firmware_Driver/inc/config.h:12:2: warning: #warning "Defaulting to Release Build" [-Wcpp]
#warning "Defaulting to Release Build"
^
In file included from ds18b20_w_lcd.cpp:2:0:
OneWire.h:20:0: warning: "FALSE" redefined [enabled by default]
#define FALSE 0
^
In file included from ../../core-common-lib/CC3000_Host_Driver/cc3000_common.h:38:0,
from ../../core-common-lib/SPARK_Firmware_Driver/inc/hw_config.h:35,
from ../inc/main.h:37,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:34,
from ../inc/application.h:29,
from ds18b20_w_lcd.cpp:2:
../../core-common-lib/CC3000_Host_Driver/data_types.h:53:0: note: this is the location of the previous definition
#define FALSE (0)
^
In file included from ds18b20_w_lcd.cpp:2:0:
OneWire.h:21:0: warning: "TRUE" redefined [enabled by default]
#define TRUE 1
^
In file included from ../../core-common-lib/CC3000_Host_Driver/cc3000_common.h:38:0,
from ../../core-common-lib/SPARK_Firmware_Driver/inc/hw_config.h:35,
from ../inc/main.h:37,
from ../inc/spark_utilities.h:30,
from ../inc/spark_wiring.h:34,
from ../inc/application.h:29,
from ds18b20_w_lcd.cpp:2:
../../core-common-lib/CC3000_Host_Driver/data_types.h:57:0: note: this is the location of the previous definition
#define TRUE (!FALSE)
^
In file included from ds18b20_w_lcd.cpp:40:0:
DS18B20.h:4:7: error: redefinition of 'class DS18B20'
class DS18B20{
^
In file included from ds18b20_w_lcd.cpp:5:0:
DS18B20.h:4:7: error: previous definition of 'class DS18B20'
class DS18B20{
^
ds18b20_w_lcd.cpp:78:1: error: expected declaration before '}' token
^
make: *** [ds18b20_w_lcd.o] Error 1
Error: Could not compile. Please review your code.
These seem to be the only important messages.
Forget about the carrets ^
to start with and look at the given line numbers and the surrounding code lines.
Try to have a look in those two ds18b29 lib files. I'll have a quick glance as well (if you can give me a link to the version you're using)
Can you locate the redefinition of DS18B20
? If you get rid of that one, the rest might go with it.
Edit: Just seen you filed another issue
http://community.spark.io/t/include-libraries-duplicates-existing-libraries-deleting-one-deletes-both/6657
this may well be in connection with it
It looks like a duplicate definition from the DS18B20.h
header. That can happen when a header file is pulled in more than once. Check that the header has
#pragma once
at the top and this will stop that from happening.
ok - thanks for your help guys.
I’m new to spark and haven’t done that much with arduino, but it seems like there are a lot of things that are not supported on spark that are available on arduino?
I’m trying to figure out the following:
rauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:79:92: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
brauduino_port_attempt.cpp:84:3: error: ‘B01000’ was not declared in this scope
unsigned long windowStartTime;
^
brauduino_port_attempt.cpp:85:3: error: ‘B10100’ was not declared in this scope
unsigned long start;
^
brauduino_port_attempt.cpp:86:3: error: ‘B01000’ was not declared in this scope
^
brauduino_port_attempt.cpp:87:3: error: ‘B00011’ was not declared in this scope
double Setpoint, Input, Output,eepromKp, eepromKi, eepromKd;
^
brauduino_port_attempt.cpp:88:3: error: ‘B00100’ was not declared in this scope
//boolean autoLoop = false;
^
brauduino_port_attempt.cpp:89:3: error: ‘B00100’ was not declared in this scope
bool manualLoop = false;
^
brauduino_port_attempt.cpp:90:3: error: ‘B00011’ was not declared in this scope
bool waterAdd = false;
^
brauduino_port_attempt.cpp:91:3: error: ‘B00000’ was not declared in this scope
bool Conv_start = false;
^
brauduino_port_attempt.cpp: In function ‘void load_pid_settings()’:
brauduino_port_attempt.cpp:254:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_c = (raw & 0xFFFC) * 0.0625;
Relevant code for above:
char* stgName[] ={
"MashIn","Stage1","Stage2","Stage3","Stage4","Stage5","Stage6","Stage7","Stage8","Boil "};
// degree c sybmol
byte degc[8] =
{
B01000,
B10100,
B01000,
B00011,
B00100,
B00100,
B00011,
B00000,
};
and:
brauduino_port_attempt.cpp:555:65: error: ‘word’ was not declared in this scope
stage_timing(stage);
I noticed that this issue was mentioned here: https://community.spark.io/t/porting-arduinolifx-a-lifx-bulb/6794/10 but I wasn’t clear on how it was resolved?
for lowByte and highByte - I just include:
#define lowByte(w) ((uint8_t)((w) & 0xFF))
#define highByte(w) ((uint8_t)((w) >> 8))
at the top of the sketch?
The sketch I’m attempting to port is here: https://github.com/mathoaus/braumiser-controller/blob/master/brauduino2.ino if you want to see if you get the same messages
@lael, first, you can ignore the warnings. For the Spark, binary values are expressed as 0Bxxxxx so you are missing the leading “zero”. There is a missing definition for “word” which could be:
#define word(h, l) (uint16_t)((h << 8) + y)
Finally, the error:
brauduino_port_attempt.cpp: In function 'void load_pid_settings()':
brauduino_port_attempt.cpp:254:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_c = (raw & 0xFFFC) * 0.0625;
I am not sure why this error exists! You are casting “raw” as an unsigned int which is 4 bytes long but then do a bitwise AND with a 16bit value. Then you multiply by a float constant. Try changing the code as follows:
uint16_t raw = word(data[1], data[0]);
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
Let me know if this works.
Thanks @peekay123 !
How do I know the differences between spark and arduino - other than by learning the hard way and asking the forum? It seems like there are a number of ‘gotchas’?
ok, trying out the solutions you proposed and getting the following errors:
#define TRUE (!FALSE)
^
brauduino_port_attempt.cpp:880:38: error: macro "word" requires 2 arguments, but only 1 given
}
^
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
^
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:82:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp: In function 'void Temperature()':
brauduino_port_attempt.cpp:23:44: error: 'y' was not declared in this scope
void stage_timing (int stage);
^
brauduino_port_attempt.cpp:216:20: note: in expansion of macro 'word'
^
brauduino_port_attempt.cpp: In function 'void load_pid_settings()':
brauduino_port_attempt.cpp:259:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
^
brauduino_port_attempt.cpp:260:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
^
brauduino_port_attempt.cpp:261:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Conv_start = false;
^
brauduino_port_attempt.cpp:264:51: error: expression list treated as compound expression in functional cast [-fpermissive]
^
brauduino_port_attempt.cpp: In function 'void get_stage_settings()':
brauduino_port_attempt.cpp:23:44: error: 'y' was not declared in this scope
void stage_timing (int stage);
^
brauduino_port_attempt.cpp:560:15: note: in expansion of macro 'word'
stage_timing(stage);
^
brauduino_port_attempt.cpp: In function 'int change_set(int&, int, int, int)':
brauduino_port_attempt.cpp:776:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
brauduino_port_attempt.cpp: In function 'int change_set(byte&, int, int, int)':
brauduino_port_attempt.cpp:795:1: warning: no return statement in function returning non-void [-Wreturn-type]
EEPROM.write(addr,data);
^
brauduino_port_attempt.cpp: In function 'void unit_set()':
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if (set_change > upper_limit)set_change = upper_limit;
^
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:809:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:23:44: error: 'y' was not declared in this scope
void stage_timing (int stage);
^
brauduino_port_attempt.cpp:815:14: note: in expansion of macro 'word'
display_lcd(0,1," ");
^
brauduino_port_attempt.cpp:807:7: warning: unused variable 'windowSizeSet' [-Wunused-variable]
display_lcd(0,1," ");
^
brauduino_port_attempt.cpp: In function 'void set_stages()':
brauduino_port_attempt.cpp:23:44: error: 'y' was not declared in this scope
void stage_timing (int stage);
^
brauduino_port_attempt.cpp:866:17: note: in expansion of macro 'word'
display_lcd(0,1,setName[i]);
^
brauduino_port_attempt.cpp:880:24: error: 'word' was not declared in this scope
}
^
make: *** [brauduino_port_attempt.o] Error 1
I removed the warnings
This should probably be
#define word(h, l) (uint16_t)((h << 8) + l)
This is the reason for
And when using this makro you'd need to supply the high and low byte.
I guess you have only supplied one value, which caused this
But to know this, we'd need to see the code snippet the compiler complains about.
Maybe if you correct these errors, others might disappear too.
Since the error messages are quite clear, I'd feel like asking, have you actually had a look at them?
And some basic cross-checking before copy-pasting code of others, might help too.
@ScruffR, OMG!!! I have to stop parking my brain like that You are correct with the syntax. As for the single argument error, I missed a line in the brauduino2.ino code that uses a single argument. To fix this, a single argument #define needs to be added:
#define word(w) (uint16_t)(w)
That and the previous definition should fix the errors.
Hi Guys,
Thanks so much for the help. ScuffR - I’m fairly new to Arduino programming and there is a lot I don’t really understand as well as I would like. The code was not written by me, which is partially why I’m having trouble understaning what to do with it to fix it. How does the word() macro actually work?
I’m getting this error now:
brauduino_port_attempt.cpp:23:0: warning: "word" redefined [enabled by default]
void stage_timing (int stage);
^
brauduino_port_attempt.cpp:22:0: note: this is the location of the previous definition
void start_time (void);
^
brauduino_port_attempt.cpp:883:39: error: macro "word" requires 2 arguments, but only 1 given
}
^
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
^
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:85:92: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp: In function 'void load_pid_settings()':
brauduino_port_attempt.cpp:262:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
^
brauduino_port_attempt.cpp:263:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
^
brauduino_port_attempt.cpp:264:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Conv_start = false;
^
brauduino_port_attempt.cpp:267:51: error: expression list treated as compound expression in functional cast [-fpermissive]
^
brauduino_port_attempt.cpp: In function 'bool wait_for_confirm(bool&)':
brauduino_port_attempt.cpp:292:1: warning: no return statement in function returning non-void [-Wreturn-type]
{ //time to shift the Relay Window
^
brauduino_port_attempt.cpp: In function 'float change_temp(float&, int, int)':
brauduino_port_attempt.cpp:322:1: warning: no return statement in function returning non-void [-Wreturn-type]
if (Button_hold_press(Button_heat)){
^
brauduino_port_attempt.cpp: In function 'int change_set(int&, int, int, int)':
brauduino_port_attempt.cpp:779:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
brauduino_port_attempt.cpp: In function 'int change_set(byte&, int, int, int)':
brauduino_port_attempt.cpp:798:1: warning: no return statement in function returning non-void [-Wreturn-type]
EEPROM.write(addr,data);
^
brauduino_port_attempt.cpp: In function 'void unit_set()':
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
if (set_change > upper_limit)set_change = upper_limit;
^
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:812:93: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
brauduino_port_attempt.cpp:810:7: warning: unused variable 'windowSizeSet' [-Wunused-variable]
display_lcd(0,1," ");
^
brauduino_port_attempt.cpp: In function 'void set_stages()':
brauduino_port_attempt.cpp:883:25: error: 'word' was not declared in this scope
}
^
make: *** [brauduino_port_attempt.o] Error 1
@lael, I did not get the double definition error on my test app but I think I know why. I believe it’s time to ditch the macros and go with two functions. Add these at the top of your app, before setup():
uint16_t word(int w) { return (uint16_t)w; }
uint16_t word(uint8_t h, uint8_t l) { return (uint16_t)((h << 8) + l); }
Don’t forget to remove or comment out the “word” macro definition.
I see - so some rough primers
So called macros - like the ones above - are "translated" by a preprocessor before the actual compiler is run.
This means, whenever the preproc finds a verb that was defined (e.g. #define word(h, l) (uint16_t)((h << 8) + l)
) somewhere before, it replaces this verb with the second part of the definition.
uint16_t x;
uint16_t hibyte = 0x12; // 0b00010010
uint16_t lobyte = 0x34; // 0b00110100
x = word(hibyte, lobyte);
will be changed into
uint16_t x;
uint16_t hibyte = 0x12; // 0b00010010
uint16_t lobyte = 0x34; // 0b00110100
x = (uint16_t)((hibyte << 8) + lobyte);
That's for the macro-question.
And now what does this do?
(uint16_t)
is a so-called type cast, which tells the compiler to treat the value represented by the following part of the expression as an uint16_t
.
And this hibyte << 8
is a 'leftshift by 8 bits' operation and causes 0x12 (0b00010010) to be changed into 0x1200 (0b0001001000000000).
And finally add the lobyte ((0x1200) + 0x34) = 0x1234.
But since macros have to be unique and are - at least by default - not distinguished by their parameter list (as C++ functions are) you got the
Which can be worked around via proper functions as @peekay123 has shown above.
One word of caution.
While the macro or function do "produce" word values, you can't use them for e.g. type casting
x = (word)somevar; // this will fail!
@ScruffR, NICE explanation!!!
@ScruffR - thank you! that is very helpful! So essentially, take two 8 bit values and put them together? Another noob question - why is this being done at all within the sketch - nevermind - I’ll take a look this afternoon and see what I can figure out and then ask to check if I understand
@peekay123
ok, so you’ve created a sketch to check it out right? I’m curious… why would yours give different results to mine? (I’m using the online editor) - if there is something I’m formatting incorrectly etc, please let me know! I did have a question - I haven’t removed the macros, only commented them out - I’m assuming the compiler won’t read them - is that correct? or does it still read some comments?
ok, these are the resulting errors:
brauduino_port_attempt.cpp: In function 'void Temperature()':
brauduino_port_attempt.cpp:220:14: error: conflicting declaration 'uint16_t raw'
}
^
brauduino_port_attempt.cpp:217:18: error: 'raw' has a previous declaration as 'unsigned int raw'
return 1;
^
brauduino_port_attempt.cpp: In function 'void load_pid_settings()':
brauduino_port_attempt.cpp:263:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_c = (raw & 0xFFFC) * 0.0625;
^
brauduino_port_attempt.cpp:264:47: error: expression list treated as compound expression in functional cast [-fpermissive]
uint16_t raw = word(data[1], data[0]);
^
brauduino_port_attempt.cpp:265:47: error: expression list treated as compound expression in functional cast [-fpermissive]
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
^
brauduino_port_attempt.cpp:268:51: error: expression list treated as compound expression in functional cast [-fpermissive]
return;
^
**and this is the code as altered:**
// This #include statement was automatically added by the Spark IDE.
#include "OneWire.h"
// This #include statement was automatically added by the Spark IDE.
#include "DS18B20.h"
// This #include statement was automatically added by the Spark IDE.
#include "PID.h"
// This #include statement was automatically added by the Spark IDE.
#include "flashee-eeprom/flashee-eeprom.h"
// This #include statement was automatically added by the Spark IDE.
#include "OneWire/OneWire.h"
// This #include statement was automatically added by the Spark IDE.
#include "LiquidCrystal/LiquidCrystal.h"
//function definitions for spark core:
#define lowByte(w) ((uint8_t)((w) & 0xFF))
#define highByte(w) ((uint8_t)((w) >> 8))
//#define word(w) (uint16_t)(w)
//#define word(h, l) (uint16_t)((h << 8) + l)
//#define word(b1,b2) (uint16_t(uint8_t(b1)<<8|uint8_t(b2)))
uint16_t word(int w) { return (uint16_t)w; }
uint16_t word(uint8_t h, uint8_t l) { return (uint16_t)((h << 8) + l); }
//pin mappings - TODO: check re-mapping to Arduino Uno
// sensor and lcd and buttons
OneWire ds(A5);
LiquidCrystal lcd(D2, D0, D3, D1, A7, D4);
// push buttons
const int Button_up = A4; //pin 12 on uno
const char Button_dn = A6;
const char Button_heat = A1; //Button_prev in org //3.3v ONLY //brauduino shield passes in 5v and will blow spark core
const char Button_pump = A0; // in org code //3.3v ONLY //brauduino shield passes in 5v and will blow spark core
// outputs
const byte Pump = D5;
const byte Buzz = A2;
const byte Heat = D6;
// global variables
unsigned int WindowSize;
unsigned long windowStartTime;
unsigned long start;
double Setpoint, Input, Output,eepromKp, eepromKi, eepromKd;
//
bool autoLoop = false;
bool manualLoop = false;
bool waterAdd = false;
bool Conv_start = false;
bool mpump = false;
bool mheat = false;
bool wtBtn = false;
bool autoEnter = false;
bool tempReached = false;
bool pumpRest = false;
//bool boilLoop = false;
bool resume = false;
float mset_temp = 35;
float Temp_c, stageTemp,pumptempError,Temp_PID;
int x;
int stageTime,hopTime;
byte mainMenu = 0;
byte pumpTime;
byte data[2];
byte second;
//byte minute;
//byte i;
byte Busy = 0;
byte nmbrStgs;
byte nmbrHops;
byte tempHAddr;
byte tempLAddr;
byte timeAddr;
byte blhpAddr;
byte hopAdd;
char* stgName[] ={
"MashIn","Stage1","Stage2","Stage3","Stage4","Stage5","Stage6","Stage7","Stage8","Boil "};
// degree c sybmol
byte degc[8] =
{
0B01000,
0B10100,
0B01000,
0B00011,
0B00100,
0B00100,
0B00011,
0B00000,
};
//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,100,20,5, DIRECT);
//****** start of the funtions**************
void Buzzer(int number)
{
for (int i=0; i < number; i++)
{
digitalWrite (Buzz,HIGH);
delay (500);
digitalWrite(Buzz,LOW);
delay(100);
}
}
void pause_stage(void){
boolean stage_pause = false;
if (Button_1sec_press(Button_heat)){
Buzzer(1);
stage_pause = true;
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
display_lcd(0,0," Paused " );
while (stage_pause)
{
if (Button_1sec_press(Button_heat))stage_pause=false;
}
}
}
void display_lcd (int pos , int line ,const char* lable){
lcd.setCursor(pos,line);
lcd.print(lable);
}
// 1 second button press
int Button_1sec_press (int Button_press){
if (digitalRead(Button_press)==0){
delay (1000);
if (digitalRead(Button_press)==0){
lcd.clear();
while(digitalRead(Button_press)==0){
}
return 1;
}
}
return 0;
}
// repeat button press
int Button_repeat (int Button_press){
if (digitalRead(Button_press)==0){
delay(200);
return 1;
}
return 0;
}
// holds whilst button pressed
int Button_hold_press (int Button_press){
if (digitalRead (Button_press)==0){
delay(50);
while (digitalRead (Button_press)==0){
}
return 1;
}
return 0;
}
// reads the DS18B20 temerature probe
void Temperature(void){
ds.reset();
ds.skip();
// start conversion and return
if (!(Conv_start)){
ds.write(0x44,0);
Conv_start = true;
return;
}
// check for conversion if it isn't complete return if it is then convert to decimal
if (Conv_start){
Busy = ds.read_bit();
if (Busy == 0){
return;
}
ds.reset();
ds.skip();
ds.write(0xBE);
for ( int i = 0; i < 2; i++) { // we need 2 bytes
data[i] = ds.read();
}
unsigned int raw = (data[1] << 8) + data[0];
Temp_PID = (raw&0xFFFF)*0.0625;
Temp_c = (raw & 0xFFFC) * 0.0625;
uint16_t raw = word(data[1], data[0]);
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
Conv_start = false;
return;
}
}
void PID_HEAT (void){
if(autoEnter){
Setpoint = stageTemp;
}
else{
Setpoint = mset_temp;
}
Input = Temp_PID;
if((Setpoint - Input)>5){
digitalWrite(Heat,HIGH);
if ((Setpoint - Input)<6)
{
myPID.Compute();
}
}
else{
myPID.Compute();
unsigned long now = millis();
if(now - windowStartTime>WindowSize)
{ //time to shift the Relay Window
windowStartTime += WindowSize;
}
if((Output*(WindowSize/100)) > now - windowStartTime) digitalWrite(Heat,HIGH);
else digitalWrite(Heat,LOW);
}
}
void load_pid_settings (void)
{
eepromKp = int(EEPROM.read(0),EEPROM.read(1));// read the PID settings from the EEPROM
eepromKi = int(EEPROM.read(2),EEPROM.read(3));
eepromKd = int(EEPROM.read(4),EEPROM.read(5));
eepromKi = eepromKi/100;
myPID.SetTunings(eepromKp,eepromKi,eepromKd); // send the PID settings to the PID
WindowSize = int(EEPROM.read(33),EEPROM.read(34));
myPID.SetOutputLimits(0, 100);
myPID.SetSampleTime(5000);
}
bool wait_for_confirm (boolean& test)
{
wtBtn = true;
while (wtBtn){ // wait for comfirmation
if (Button_hold_press(Button_heat)){
test = true;
wtBtn = false;
lcd.clear();
}
if (Button_hold_press(Button_pump)){
test = false;
wtBtn = false;
lcd.clear();
}
}
}
float change_temp(float& temp_change,int upper_limit,int lower_limit)
{
// Increase set temp
if (Button_repeat(Button_up)){
if (temp_change>=100){
temp_change++;
}
else{
temp_change+=0.25;
}
if (temp_change > upper_limit)temp_change = upper_limit;
}
// decrease temp
if (Button_repeat(Button_dn))
{
if(temp_change>=100){
temp_change--;
}
else{
temp_change-=0.25;
}
if ( temp_change < lower_limit) temp_change = lower_limit;
}
}
void quit_mode (boolean& processLoop)
{
if ((digitalRead(Button_dn)==0) && (digitalRead(Button_up)==0)){
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
processLoop = false;
lcd.clear();
}
}
void heat_control(void)
{
//turns heat on or off
if (Button_hold_press(Button_heat)){
if (mheat==false){
mheat = true;
windowStartTime = millis();
}
else{
mheat = false;
digitalWrite(Heat,LOW);
}
}
}
void pump_control(void)
{
//turns the pump on or off
if (Button_hold_press(Button_pump)){
if (mpump == false){
mpump = true;
digitalWrite(Pump,HIGH);
}
else{
mpump = false;
digitalWrite(Pump,LOW);
}
}
}
void prompt_for_water (void){
display_lcd(0,0," Water added? ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
}
void pump_prime(void)
{
lcd.clear();
lcd.print(" Pump Prime "); // priming the pump
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
delay(200);
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
delay(200);
digitalWrite(Pump,HIGH);
delay (1000);
digitalWrite(Pump,LOW);
lcd.clear();
}
void pump_rest (int stage)
{
if (stage==9){
if (Temp_c<94.0) digitalWrite(Pump,HIGH);
else digitalWrite(Pump,LOW);
if (Temp_c >= 95)tempReached = true;
}
else{
pumptempError = stageTemp-Temp_c;
if (pumptempError <= 0)tempReached = true;
if ((pumpTime < 10)){ // starts pumps and heat
digitalWrite(Pump,HIGH);
pumpRest =false;
}
if ((pumpTime >= 10)){ // pump rest
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
pumpRest = true;
if(pumpTime>=12 || (pumptempError > 1.0))pumpTime = 0;
}
}
}
void check_for_resume(void){
if(EEPROM.read(35)){ // read the auto started byte to see if it has been set and if so ask to resume
display_lcd (0,0," Resume Process?");
display_lcd (0,1," Yes No");
wait_for_confirm(resume);
if(resume==true){
tempHAddr = (EEPROM.read(36)*3)+6;
tempLAddr = tempHAddr+1;
timeAddr = tempHAddr+2;
x = EEPROM.read(36);
autoEnter = true;
lcd.clear();
}
}
}
void load_stage_settings (void){
tempHAddr = 6; // setup intitial stage addresses
tempLAddr = 7;
timeAddr = 8;
nmbrStgs = EEPROM.read(38);// read the number of steps
nmbrHops = EEPROM.read(39);//read the number of hop additions
}
void start_time (void)
{
start = millis();
// windowStartTime = millis();
second = 0;
// minute = 0;
}
void stage_timing (int stage)
{
if ((millis()-start)>1000){ // timing routine
start = millis();
second++;
if(!(tempReached))second=0;// starts counting down when temp reached
if (second>59){
display_lcd(10,0," ");
second = 0;
pumpTime++;
if(stage == 0)pumpTime = 0;
stageTime--;
EEPROM.write(37,lowByte(stageTime));// saves stage time incase of interuption
}
}
}
void hop_add (void)
{
if(hopAdd <= nmbrHops){
if (stageTime == hopTime){
Buzzer(3);
lcd.clear();
lcd.print(" Add Hops");
delay(2000);
Buzzer(3);
hopAdd++;
EEPROM.write(49,hopAdd);
blhpAddr++;
hopTime = EEPROM.read(blhpAddr);
lcd.clear();
}
}
}
void stage_loop (int stage, float H_temp=80, float L_temp=30){
int lastminute;
while ((stageTime>0)&&(autoEnter)){
lastminute=stageTime;
stage_timing(stage);
Temperature();// get temp
pause_stage();
if (pumpRest){
display_lcd(0,0," Pump Rest ");
display_lcd(0,1," ");
}
else{
display_lcd(0,0,stgName[stage]);
display_lcd(6,0," ");
display_lcd(11,0,"T=");
lcd.print(stageTime);
display_lcd(0,1,"S/A=");
lcd.print(stageTemp);
display_lcd(9,1,"/");
lcd.print(Temp_c);
lcd.write((uint8_t)0);
}
change_temp(stageTemp,H_temp,L_temp);
pump_rest(stage);
if (pumpRest==false)PID_HEAT();
if (stage==9){
if(stageTime<lastminute){
hop_add();
}
}
quit_mode (autoEnter);
}
}
void get_stage_settings (void)
{
stageTemp = word(EEPROM.read(tempHAddr),EEPROM.read(tempLAddr));
stageTemp = stageTemp/16.0;
if (resume){ // on the start of resume gets saved time
stageTime=EEPROM.read(37);
resume = false; // clears resume for next loop
}
else{
stageTime = EEPROM.read(timeAddr); // gets stage time
EEPROM.write(37,lowByte(stageTime));// saves the intial stage time
}
}
void add_malt (void)
{
boolean malt;
lcd.clear();
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
display_lcd(0,0," Add Malt ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
wait_for_confirm(malt);
if (malt==false){
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
lcd.clear();
delay(50);
mainMenu=0;
autoEnter = false;
}
}
void remove_malt (void)
{
boolean malt;
lcd.clear();
x = 9; // used add to stage count on the final stage for the resume
EEPROM.write(36,lowByte(x)); // stores the stage number for the resume
digitalWrite(Pump,LOW);
digitalWrite(Heat,LOW);
display_lcd(0,0," Remove Malt ");
Buzzer(3);
display_lcd(0,1," Ok Quit");
wait_for_confirm(malt);
if (malt==false){
stageTime = EEPROM.read(40);
EEPROM.write(37,lowByte(stageTime));
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
lcd.clear();
delay(50);
mainMenu=0;
autoEnter = false;
}
}
void get_boil_settings (void)
{
nmbrHops = EEPROM.read(39);
if (resume){
if(x!=9){
stageTime = EEPROM.read(40);
}
else{
stageTime= EEPROM.read(37);
}
}
else{
stageTime = EEPROM.read(40);
EEPROM.write(37,lowByte(stageTime));
}
hopAdd = EEPROM.read(49);
blhpAddr = hopAdd+41;
lcd.clear();
hopTime = EEPROM.read(blhpAddr);
}
void manual_mode (void)
{
load_pid_settings();
prompt_for_water();
wait_for_confirm(manualLoop);
while (manualLoop){ // manual loop
Temperature();
display_lcd(0,0," Manual Mode ");
display_lcd(0,1,"S/A=");
lcd.print(mset_temp);
display_lcd(9,1,"/");
lcd.print(Temp_c);
lcd.write((uint8_t)0);
change_temp(mset_temp,120,20);
quit_mode(manualLoop);
heat_control();
pump_control();
if (mheat){
PID_HEAT();
}
}
}
void auto_mode (void)
{
load_stage_settings();
load_pid_settings();
check_for_resume();
if(!(resume)){ // if starting a new process prompt for water
prompt_for_water();
wait_for_confirm(autoEnter);
if(!(autoEnter))return;
pump_prime();
x = 0;
}
if (autoEnter){ // mash steps
EEPROM.write(35,1);// auto mode started
for (int i = x;i < nmbrStgs;i++){
EEPROM.write(36,lowByte(x)); // stores the stage number for the resume
x++; // used to count the stages for the resume
tempReached = false;
get_stage_settings();
start_time();
stage_loop(i);
if (!(autoEnter)) break;
if( i==0 && autoEnter){ // at the end of the mashIn step pauses to add grain
add_malt();
if (!(autoEnter))break;
}
if(i==(nmbrStgs-1)&& autoEnter){ // at the end of the last step pauses to remove the malt pipe before the boil
remove_malt();
if (!(autoEnter))break;
}
Buzzer(1);
tempHAddr +=3; // increase stage addresses
tempLAddr +=3;
timeAddr +=3;
lcd.clear();
}
}
// start of the boil
if(autoEnter){
start_time();
stageTemp= 98.0; // set the intital boil temp to 98 deg c
tempReached = false;
get_boil_settings();
stage_loop(9,120,94);
if(autoEnter){ // finishes the brewing process
display_lcd(0,0," Brewing ");
display_lcd(0,1," Finished ");
Buzzer(3);
delay(2000);
EEPROM.write(35,0); // sets auto start byte to 0 for resume
EEPROM.write(49,0); // sets hop count to 0
mainMenu=0;
autoEnter =false;
resume =false;
}
}
}
void save_settings (int addr,int data)
{
EEPROM.write(addr,highByte(data));
EEPROM.write((addr+1),lowByte(data));
}
void save_settings (int addr,byte data){
EEPROM.write(addr,data);
}
int change_set(int& set_change,int upper_limit,int lower_limit,int step_size)
{
// Increase set temp
if (Button_repeat(Button_up)){
set_change+=step_size;
display_lcd(0,1," ");
}
if (set_change > upper_limit)set_change = upper_limit;
// decrease temp
if (Button_repeat(Button_dn))
{
set_change-=step_size;
display_lcd(0,1," ");
}
if ( set_change < lower_limit) set_change = lower_limit;
}
int change_set(byte& set_change,int upper_limit,int lower_limit,int step_size)
{
// Increase set temp
if (Button_repeat(Button_up)){
set_change+=step_size;
display_lcd(0,1," ");
}
if (set_change > upper_limit)set_change = upper_limit;
// decrease temp
if (Button_repeat(Button_dn))
{
set_change-=step_size;
display_lcd(0,1," ");
}
if ( set_change < lower_limit) set_change = lower_limit;
}
void unit_set (void)
{
int param[] ={
100,-100,1,100,-100,1,100,-100,1,5000,500,500,9,1,1,8,0,1 };
int a = 0;
boolean pidLoop = false;
int pidSet,setaddr;
int windowSizeSet;
char* setName[] ={
"Kp = ","Ki = ","Kd = ","Windowsize= ","Num of Stages=","Num of Hops=" };
setaddr = 0;
for(int i=0;i<6;i++){
if((i>=0) && (i<=3)){
if (i==3) setaddr = 33;
pidSet=word(EEPROM.read(setaddr),EEPROM.read((setaddr+1)));
}
if (i==4)setaddr = 38;
if((i>=4) && (i<6)){
pidSet= EEPROM.read(setaddr);
}
pidLoop= true;
display_lcd(0,1," ");
while (pidLoop){
display_lcd(0,1,setName[i]);
lcd.print(pidSet);
change_set(pidSet,param[a],param[a+1],param[a+2]);
quit_mode(pidLoop);
if (!(pidLoop))i=6;
if(Button_hold_press(Button_pump)){
if (i >= 4){
save_settings(setaddr,lowByte(pidSet));
pidLoop = false;
}
else{
save_settings(setaddr,pidSet);
pidLoop = false;
}
}
}
if (i>=4){
setaddr+=1;
}
else{
setaddr+=2;
}
a+=3;
}
}
void set_stages (void)
{
boolean autotempLoop = false;
boolean autotimeLoop = false;
tempHAddr = 6;
tempLAddr = 7;
timeAddr = 8;
float stgtmpSet;
int stgtmpSetword;
int stgtimSet;
nmbrStgs = EEPROM.read(38);
for (int i=0; i<nmbrStgs;i++){ // loops for the number of stages
stgtmpSet = word(EEPROM.read(tempHAddr),EEPROM.read(tempLAddr));
stgtmpSet = stgtmpSet/16.0;
autotempLoop = true;
while (autotempLoop){ // loops for temp adjust
display_lcd(0,1,stgName[i]);
lcd.print("Temp=");
lcd.print(stgtmpSet);
quit_mode(autotempLoop);
if (autotempLoop == false){
return;
}
change_temp(stgtmpSet,85,20);
if (Button_hold_press(Button_pump)){
stgtmpSet = stgtmpSet*16;
stgtmpSetword = word(stgtmpSet); //**error here word requires two par?
save_settings(tempHAddr,stgtmpSetword);
display_lcd(0,1," ");
autotempLoop = false;
}
}
autotimeLoop = true;
stgtimSet = EEPROM.read(timeAddr);
while (autotimeLoop){ // loops to adjust time setting
display_lcd(0,1,stgName[i]);
lcd.print(" time=");
lcd.print(stgtimSet);
quit_mode(autotimeLoop);
if (autotimeLoop == false){
return;
}
change_set(stgtimSet,120,0,1);
if (Button_hold_press(Button_pump)){
save_settings(timeAddr,lowByte(stgtimSet));
display_lcd(0,1," ");
autotimeLoop = false;
}
}
tempHAddr+= 3;
tempLAddr+= 3;
timeAddr+= 3;
}
}
void set_hops (void)
{
boolean hopLoop = false;
blhpAddr = 40;
byte hopSet;
nmbrHops = EEPROM.read(39);
nmbrHops+=1;
for(int i =0;i<nmbrHops;i++){
hopLoop = true;
hopSet = EEPROM.read(blhpAddr);
while (hopLoop){
if (i==0){
display_lcd(0,1,"Boil time = ");
lcd.print(int (hopSet));
}
else{
display_lcd(0,1,"Hop ");
lcd.print(i);
lcd.print(" time = ");
lcd.print(int(hopSet));
}
quit_mode(hopLoop);
if( hopLoop == false){
return;
}
change_set(hopSet,180,0,1);
if (Button_hold_press(Button_pump)){
save_settings(blhpAddr,hopSet);
lcd.setCursor(0,1);
lcd.print(" ");
hopLoop = false;
}
}
blhpAddr+= 1;
}
}
void auto_set(void)
{
set_stages();
set_hops();
}
void setup_mode (void)
{
byte setupMenu = 0;
boolean setupLoop = true;
while (setupLoop){
switch (setupMenu){ // to select between PID and Auto menu
case(0):
display_lcd(0,0,"Unit Parameters ");
display_lcd(0,1," ");
quit_mode(setupLoop);
if (Button_hold_press(Button_up))setupMenu = 1;
if (Button_hold_press(Button_pump))unit_set();
break;
case(1):
display_lcd(0,0," Auto Parameters");
display_lcd(0,1," ");
quit_mode(setupLoop);
if (Button_hold_press(Button_dn))setupMenu = 0;
if (Button_hold_press(Button_pump))auto_set();
break;
}
}
}
void setup()
{
// Start up the library
lcd.begin(20,4);
pinMode (Button_up,INPUT);
pinMode (Button_dn,INPUT);
pinMode (Button_heat,INPUT);
pinMode (Button_pump,INPUT);
pinMode (Heat,OUTPUT);
pinMode (Pump,OUTPUT);
pinMode (Buzz,OUTPUT);
windowStartTime = millis();
//tell the PID to range between 0 and the full window size
myPID.SetMode(AUTOMATIC);
// write custom symbol to LCD
lcd.createChar(0,degc);
}
void loop() {
switch(mainMenu){
case (1):
display_lcd(0,0," Manual Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
manual_mode();
mainMenu = 0;
break;
case (2):
display_lcd(0,0," Auto Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
auto_mode();
mainMenu = 0;
break;
case (3):
display_lcd(0,0," Setup Mode ");
display_lcd(0,1," ");
delay (1000);
lcd.clear();
setup_mode();
mainMenu = 0;
break;
default:
digitalWrite(Heat,LOW);
digitalWrite(Pump,LOW);
Temperature();
display_lcd(0,0," The Brauduino ");
display_lcd(0,1," Temp=");
lcd.print(Temp_c);
lcd.write((uint8_t)0);
if (Button_1sec_press(Button_dn))mainMenu = 1;
if (Button_1sec_press(Button_heat))mainMenu = 2;
if (Button_1sec_press(Button_pump))mainMenu = 3;
break;
}
}
I would recommend posting this in Gist an share the link.
it’s too much code and make it hard to navigate this thread.
Git? Do you know of a good IDE for windows for it?
I meant Gist.
like this?:
Sorry, to be so blunt, but even if you're new to C/C++, Arduino and Spark Core, as said above please read the error messages and look at your own code.
You have a pretty clear error message here
and then you have this code with code lines 217 and 220 and they do actually line up with the gist you posted
unsigned int raw = (data[1] << 8) + data[0]; // line 217 is the previous declaration of raw
Temp_PID = (raw&0xFFFF)*0.0625;
Temp_c = (raw & 0xFFFC) * 0.0625;
uint16_t raw = word(data[1], data[0]); // and here in line 220 you re-declare the SAME variable as different type
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
Change this into
uint16_t raw = (data[1] << 8) + data[0]; // is the same as unsigned int on 8/16 bit processors
Temp_PID = (raw & 0xFFFF) * 0.0625;
Temp_c = (raw & 0xFFFC) * 0.0625;
//
/* Why do you do exactly the same thing twice, anyway????
raw = word(data[1], data[0]); // don't re-declare but only use the already declared variable
Temp_PID = (float)(raw & 0xFFFF) * 0.0625;
Temp_c = (float)(raw & 0xFFFC) * 0.0625;
*/
//
This would have been easy to find out.
The other errors
for lines 263, 264, 265 and 268 are quite clear as well, when you look at these lines
void load_pid_settings (void)
{
eepromKp = int(EEPROM.read(0),EEPROM.read(1)); // 263
eepromKi = int(EEPROM.read(2),EEPROM.read(3)); // 264
eepromKd = int(EEPROM.read(4),EEPROM.read(5)); // 265
eepromKi = eepromKi/100;
myPID.SetTunings(eepromKp,eepromKi,eepromKd); // send the PID settings to the PID
WindowSize = int(EEPROM.read(33),EEPROM.read(34)); // 268
myPID.SetOutputLimits(0, 100);
myPID.SetSampleTime(5000);
}
int
is not a macro or a function as you might assume after using word
this way.
That was why I stated "A word of caution", above. A type is not a macro/function and vice versa.
But you could use the word
macro/function there to do what you intended.