Processing Front-End for the PID Library

That could certainly be the case. as you said, the arduino->processing communication is in the form of a string, which is not the most efficient way to send numbers :slight_smile:

the first thing to try would be upping the communication speed and see if that fixes the problem. I think I set it at 9600, but the arduino will support up to 115200.

if you wanted to keep the comm rate the same, another option would be to send Arduino->processing information less often. Currently it's every 500ms (serialTime+=500;)

Of course, this all assumes that the issue is too much information being sent. Hopefully that's it, and one of the above solutions takes care of the problem.

-Brett

Brett,

I tried increasing the print incremental time to 1sec and increasing the baud rate to 19200 and it still wasn't working. I tried increasing the serial read buffer until 11 in the processing front end and the error messages went away, however none of the fields updated and it doesn't seem to read in any data. Could this be the choking point on the data flow?

Evan

Nevermind, I figured out why it wasn't working. That 10 in there was ASCII. I got it working now.

Has anybody heard of a PID library for Processing?
Im thinking: The frontend has lots of power, so why not do the PID math here and only run Firmata on the Arduino.
I assume it is not possible to use Arduino libs in Processing.
/Preben

Has anybody heard of a PID library for Processing?

I've never written a processing library before, but my guess is porting the arduino version should be pretty easy. the only arduino function it calls is millis().

I'll see if I can bang one out this weekend

Brett

hi,

thanks brett great program has helped me a lot, i am also using your frontend for my home brewery, and im trying to add a stir button to control a stir motor. I tried the code you gave EVAN but i dont know how to take the byte sent and apply it to my stirmotor Pin's output. Could you please point me in the right direction, your help would be much appreciated.

Thanks,
mooooks.

mooooks, assuming you copied evan's front-end code, the byte being sent should be a 0 or 1. the code I posted in reply#11 takes this byte and puts it into "pump_OnOff".

after that it should be a matter of doing a:
digitalWrite(outputPin, pump_OnOff);

I don't have my arduino on me, so I can't test this. if the above doesn't work you may need to tell the compiler "look man, I know the value in pump_OnOff is only ever going to be 0 or 1":
digitalWrite(outputPin, (boolean)pump_OnOff);

Hope this helps,
Brett

Thanks Brett,
when sending byte c from processing i was sending it as "mode" when it should have been "PUMPmode", e.g Byte c = (PUMPmode=="ON")?(byte)0:(byte)1;.
All working now thanks.

Okay I have the whole processing program running... pulls up the UI but when I click the button to go to automatic and send it to the arduino it doesn't change the value listed next to the box, but I can see the arduino blink when i click the button which means it should be communicating... I see no lines anywhere on the graph and can't figure out why it's not working!
I've got the arduino plugged in and set to port dev/tty.usbserial-A800-ev1H. When i load up processing the list in the box below the text field says

Stable Library

Native lib Version = RXTX-2.1-7
Java lib Version = RXTX-2.1-7
[0] "/dev/tty.usbserial-A800ev1H"
[1] "/dev/cu.usbserial-A800ev1H"
[2] "/dev/tty.Bluetooth-PDA-Sync"
[3] "/dev/cu.Bluetooth-PDA-Sync"
[4] "/dev/tty.Bluetooth-Modem"
[5] "/dev/cu.Bluetooth-Modem"
ControlP5 0.5.0 infos, comments, questions at processing GUI, controlP5

I have input on my arduino coming in on analog in 0 and analog 2... I have my output through digital pin 3. I have the following program loaded to my arduino.

/********************************************************
 * PID Simple Example
 * Reading analog input 0 to control analog PWM output 3
 ********************************************************/

#include <PID_Beta6.h>

//Define Variables we'll be connecting to
double Setpoint, Input, Output;

//Specify the links and initial tuning parameters
PID myPID(&Input, &Output, &Setpoint,9,9,9);

void setup()
{
  //initialize the variables we're linked to
  Input = analogRead(2) - analogRead(0);
  Setpoint = 600;

  //turn the PID on
  //myPID.SetMode(AUTO);
  //Serial.begin(9600);
}

void loop()
{
  Input = analogRead(2) - analogRead(0);
  //Serial.println(Input);
  myPID.Compute();
  analogWrite(3,Output);
  
  //Serial.print("output: ");
  //Serial.println(Output);
}

Does anyone have any idea why this is happening? I don't get any compiling/loading errors anywhere so I'm not sure why this is happening!

Lance, If you posted your entire program then I think I know what the problem is. there's code you need to implement on the arduino side to listen for the signals from processing.

Take a look at the sample arduino program that's bundled with the Processing front-End. try loading that onto your arduino and see if the problem persists.

Brett

Oh man... Well at least it was an easy fix! Works perfectly now, I had always assumed that was another Processing file, never extended the window and read the whole file name lol.

Thanks for the help

Well, I have a strange problem.

I can't get any output from my pid-controller even if i change my PID constants i.e. tuning. Here is what i am doing.

double MagStartPositionY = 375;
double MagReadingsInts[3];
double YawServoOffset = 0;

//Yaw PID control
#define Input MagReadingsInts[1]
#define Output YawServoOffset
#define SetPoint MagStartPositionY

double P_Param = 0.5; //0.004
double I_Param = 0.01; //0.009
double D_Param = 0; //0.3

PID YawPID(&MagReadingsInts[1], &YawServoOffset, &MagStartPositionY, P_Param, I_Param, D_Param);

void setup()
{
//Some Code//
YawPID.SetOutputLimits(0,30); // I want output to be a number from 0-30
YawPID.SetMode(AUTO); //turn on the PID
}

void loop()
{

// Code to receive data is correct
...................

//
YawPID.compute();
Serial.print("Output : ");Serial.println(Output);
delay(2000);

}

My input is the serial Magnetometer data. I move my magnetometer to change the input and want to see how output changes. But strangely output always remain zero.

I tried putting YawPID.SetTunings(P_K,I_K,D_K); and changing the input, output and setpoint definitions to double but all in vain.

Can anybody figure out what is the problem?

Thanks!

Hi there,

I am attempting to get the frontend working for the PID library and I've hit something of a snag. I am getting the following error when I run the program in Processing:

error, disabling serialEvent() for /dev/ttyUSB0
java.lang.reflect.InvocationTargetException
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      at java.lang.reflect.Method.invoke(Method.java:616)
      at processing.serial.Serial.serialEvent(Unknown Source)
      at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
      at gnu.io.RXTXPort.eventLoop(Native Method)
      at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)
Caused by: java.lang.NullPointerException
      at PID_FrontEnd_v02.serialEvent(PID_FrontEnd_v02.java:436)
      ... 8 more

The graphical display comes up but no data is passed to or received from the arduino. Nothing comes up on the graph or in the data fields to the left.

I was able to eliminate the error by removing the setValue() and setText() commands in serialEvent(). If I comment out those lines, like this:

//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;
  }
}

Again, the graphical window comes up, but some data starts coming from the arduino (the led starts blinking), and it begins drawing the setpoint, input, and output lines. The data fields to the left do not show anything. However, I can change the setpoint, "Send to Arduino" and the green line will reflect the change.

I've read around a bit about this error, but I still don't understand what's going on.

Do you have any thoughts?

BTW I'm running on Ubuntu, if that makes any difference.

EDIT: I just tried this on a windows laptop and it worked with no errors. It must be specific to Linux or Ubuntu versions of processing.

EDIT2: This thread is the closest I've come to a similar error, but its from 2007, and they don't have a solution:

http://processing.org/discourse/yabb2/YaBB.pl?num=1183525352

Brett,

This GUI has been awesome for playing with the PID library more productively. I am now trying to record some data sets and run them through some system ID code in Matlab so I can do model-based gain selection. (And then I can use it to control the temperature of my mash for homebrewing =)

I am finding that when I give an output file name to the frontend code, it creates an empty file but never writes anything to it. I was able to fix the problem by adding output.flush() immediately after the output.println(). Is there a way to cleanly close the frontend? I didn't see an output.close() or any other wrap-up stuff, so I'm wondering if anyone has been using the write to file feature.

Thanks!

I'm wondering if anyone has been using the write to file feature.

in all honesty I threw that in there to do what you are doing, but it's been a while since I've used it. since then there's been a new version of processing, a new windows OS, and a few tweaks to the code.

the not-closing-cleanly thing is something I just plain missed.
Brett

Cool. If you're going through that code anytime soon, another recommendation I'd have is matching the specific string "PID" before trying to parse a line of serial data - I've run into trouble where other debugging strings I've printed happen to have 8 space-separated strings and confuse the frontend.

Please consider keeping PID Library an active project. I personally love it.

in all honesty I threw that in there to do what you are doing, but it's been a while since I've used it. since then there's been a new version of processing, a new windows OS, and a few tweaks to the code.

the not-closing-cleanly thing is something I just plain missed.
Brett

Nice.good working in graphics

Hey Everyone,

I'm desperately trying to get this front-end to work, but I keep getting the following error when I try to run it in the Processing program:

Note that release 1.0, libraries must be installed in a folder named 'libraries' inside the 'sketchbook' folder.

My "sketchbook" is defined as being in "My Documents/Processing" per the Preferences in Processing. I created a "libraries" folder there and placed the "controlP5" folder in it. I've also made "libraries" folders all over the place trying to get this to work. Any idea what I could be doing wrong?

Thanks,
Patrick