Brett,
I really love this program. It works great for my home brewery automation project that I have been working on. In my project I have a pump recirculating fluid through a copper tubing array immersed in a larger pipe containing water and an electrical heater. I have gotten the pid working on heating the water in larger pipe thus heating the fluid inside the copper array, but the pump is running continuously from the code on the arduino, which makes it a little hard to stop if I need to stop it for some reason. I tried adding a button on the front end with success, but I am having trouble returning it to the arduino. I got stuck at the point when you change the floats to characters and throw them in the array that passes between both programs. I was wondering if I could get some expert advice on how to proceed. I've gotten to this point. I tried to post all of the code, but since it was too long I just posted the parts that I've made changes to. Hopefully you will be able to make sense of this,
Serial myPort;
ControlP5 controlP5;
controlP5.Button AMButton;
controlP5.Button PUMPButton;
controlP5.Textlabel AMLabel, AMCurrent, InLabel,
OutLabel, SPLabel, PLabel, PUMPLabel, PUMPCurrent,
ILabel, DLabel;
controlP5.Textfield SPField, InField, OutField,
PField, IField, DField;
PrintWriter output;
PFont AxisFont, TitleFont;
void setup()
{
frameRate(30);
size(windowWidth , windowHeight);
println(Serial.list()); // * Initialize Serial
myPort = new Serial(this, Serial.list()[1], 9600); // Communication with
myPort.bufferUntil(10); // the Arduino
controlP5 = new ControlP5(this); // * Initialize the various
SPField= controlP5.addTextfield("Setpoint",10,100,60,20); // Buttons, Labels, and
InField = controlP5.addTextfield("Input",10,150,60,20); // Text Fields we'll be
OutField = controlP5.addTextfield("Output",10,200,60,20); // using
PField = controlP5.addTextfield("P_Param",10,275,60,20); //
IField = controlP5.addTextfield("I_Param",10,325,60,20); //
DField = controlP5.addTextfield("D_Param",10,375,60,20); //
AMButton = controlP5.addButton("Toggle_AM",0.0,10,50,60,20); //
AMLabel = controlP5.addTextlabel("AM","Manual",12,72); //
AMCurrent = controlP5.addTextlabel("AMCurrent","Manual",80,65); //
controlP5.addButton("Send_To_Arduino",0.0,10,425,120,20); //
PUMPButton = controlP5.addButton("Toggle_Pump",0.0,10,475,60,20); //
PUMPLabel = controlP5.addTextlabel("ON","OFF",12,497); //
PUMPCurrent = controlP5.addTextlabel("ONCURRENT","OFF",80,485); //
SPLabel=controlP5.addTextlabel("SP","3",80,103); //
InLabel=controlP5.addTextlabel("In","1",80,153); //
OutLabel=controlP5.addTextlabel("Out","2",80,203); //
PLabel=controlP5.addTextlabel("P","4",80,278); //
ILabel=controlP5.addTextlabel("I","5",80,328); //
DLabel=controlP5.addTextlabel("D","6",80,378); //
AxisFont = loadFont("axis.vlw");
TitleFont = loadFont("Titles.vlw");
nextRefresh=millis();
if (outputFileName!="") output = createWriter(outputFileName);
}
String PUMPmode = "ON";
void Toggle_PUMP() {
if(PUMPmode=="ON")
{
PUMPmode = "OFF";
PUMPLabel.setValue(PUMPmode);
}
else
{
PUMPmode = "ON";
PUMPLabel.setValue(PUMPmode);
}
}
// Sending Floating point values to the arduino
// is a huge pain. if anyone knows an easier
// way please let know. the way I'm doing it:
// - Take the 6 floats we need to send and
// put them in a 6 member float array.
// - using the java ByteBuffer class, convert
// that array to a 24 member byte array
// - send those bytes to the arduino
void Send_To_Arduino()
{
float[] toSend = new float[6];
toSend[0] = float(SPField.getText());
toSend[1] = float(InField.getText());
toSend[2] = float(OutField.getText());
toSend[3] = float(PField.getText());
toSend[4] = float(IField.getText());
toSend[5] = float(DField.getText());
Byte b = (mode=="Manual")?(byte)0:(byte)1;
Byte c = (mode=="ON")?(byte)0:(byte)1;
myPort.write(b);
myPort.write(c);
myPort.write(floatArrayToByteArray(toSend));
justSent=true;
}
byte[] floatArrayToByteArray(float[] input)
{
int len = 4*input.length;
int index=0;
byte[] b = new byte[4];
byte[] c = new byte[4];
byte[] out = new byte[len];
ByteBuffer buf = ByteBuffer.wrap(b);
ByteBuffer buf = ByteBuffer.wrap(c);
for(int i=0;i<input.length;i++)
{
buf.position(0);
buf.putFloat(input[i]);
for(int j=0;j<4;j++) out[j+i*4]=b[3-j];
}
return out;
}
//take the string the arduino sends us and parse it
void serialEvent(Serial myPort)
{
String read = myPort.readStringUntil(10);
if(outputFileName!="") output.print(str(millis())+ " "+read);
String[] s = split(read, " ");
if (s.length ==8)
{
Setpoint = float(s[1]); // * pull the information
Input = float(s[2]); // we need out of the
Output = float(s[3]); // string and put it
SPLabel.setValue(s[1]); // where it's needed
InLabel.setValue(s[2]); //
OutLabel.setValue(trim(s[3])); //
PLabel.setValue(trim(s[4])); //
ILabel.setValue(trim(s[5])); //
DLabel.setValue(trim(s[6])); //
AMCurrent.setValue(trim(s[7])); //
if(justSent) // * if this is the first read
{ // since we sent values to
SPField.setText(trim(s[1])); // the arduino, take the
InField.setText(trim(s[2])); // current values and put
OutField.setText(trim(s[3])); // them into the input fields
PField.setText(trim(s[4])); //
IField.setText(trim(s[5])); //
DField.setText(trim(s[6])); //
mode = trim(s[7]); //
AMLabel.setValue(mode); //
justSent=false; //
} //
if(!madeContact) madeContact=true;
}
}
I would really appreciate any help you can provide or anyone else that has had luck with doing something similar.
Thanks,
Evan