-
• #2
I think you want to do:
var p=new PID(...);
(Also, I'm pretty sure the code won't work without a bit of work to port to the Espruino) .
-
• #3
Take a look to this node.js module. Its a simple solution.
https://github.com/philmod/node-pid-controller -
• #4
I haven't tried it, but it should work with minor tweaks. I guess the first things to try would be:
- copy+paste https://github.com/wilberforce/pid-controller/blob/master/lib/index.js into the right-hand pane.
- Replace
PID.prototype.millis
withPID.prototype.millis = function() { return getTime()*1000;}
Just use it like in the example (without the require):
var ctr = new PID(50, 66, 10,2,1, PID.DIRECT ) ctr.setMode(ctr.AUTOMATIC); ctr.setTunings(10,2,1); ctr.setOutputLimits(0,100); ctr.setInput(temp);
If it works well, I guess we could add the module to Espruino?
Have you done much work in other Object oriented languages? It's probably wrong but I tend to think of the prototype system as follows (and it works for me :) :
function Foo() { ... } // the constructor (but also the name of the class) Foo.prototype // a list of the class methods and 'static' properties Foo.prototype.bar = function() { ... } // define one of the Class's methods Foo.prototype.baz = 42; // define a value that is shared between all instances of the class. In C++/Java this would be called 'static' var a = new Foo(); // An object of class Foo var b = new Foo(); a.x = "Test"; console.log(b.x); // prints undefined - x wasn't in the prototype so is unique to the 'a' Object console.log(a.baz); // prints 42 - from the prototype a.baz = "Hello"; console.log(b.baz); // prints 'Hello' - baz was in the prototype, so it's shared between instances of Foo Foo.prototype.hello = function() { console.log(this.x); // access the Object with 'this' } a.hello(); // prints "Test". In the 'hello' function, 'this' is the same value as 'a'.
It all stems from some pretty simple rules in the interpreter. Each object is nothing more than a list of key/value pairs, and:
When you say
foo = new Foo()
, it effectively just doesfoo = Foo(); foo.__proto__ = Foo.prototype
.Then, if you access
foo.bar
:foo
is searched for something namedbar
. If that exists, it's returned.- Otherwise, if
foo
has a field named__proto__
, that is searched forbar
and it's returned if found - Otherwise, if we found
__proto__
in the last step, see if there's a__proto__
inside that, and so on. - Or if nothing was found, simply return undefined (but if you're doing
foo.bar= ...
, it'll simply directly setbar
onfoo
).
So it's actually a really simple way of getting something like an Object Oriented language. I always find if I want to know what's going to happen, I can basically walk through the steps above.
Does that help explain it at all?
- copy+paste https://github.com/wilberforce/pid-controller/blob/master/lib/index.js into the right-hand pane.
-
• #5
@JumJum - I did find that one first, but I figured if we are going to have a module for the Espruino it had better have all the bells and whistles.
This version from Rhys Williams is ported from Brett Beauregard's Arduino version which was pretty well documented on his blog a few years ago.@Gordon - No never really done any object oriented stuff, just simple bits and pieces. I seem to learn best by hacking away at other examples to understand whats going on. But I will definitely refer to your example.
I had pretty much figured it out what you had with the PID code.
The only issue may be when the value that is returned from getTime() rolls over.
It appears to be working using a few simple tests (finger on thermistor) watch demand decrease, finger off thermistor watch demand increase.
-
• #6
Great! I did an example with a simple relay and really nasty control system. I'd love to see something similar with PWM and temperature sensing :)
As far as the rollover, getTime() returns a double (which realistically will never roll over), and internally it's calculated from the RTC, which will only roll over after 136 years of continuous use - so I'm not sure it's such a big deal.
-
• #7
Just to say, that library is expecting the Arduino-style 'loop', so
compute
basically polls to see when it should do stuff. It'd be much better if it was re-written to usesetInterval
, with maybe a callback for when the output value changes. -
• #8
Unfortunately I don't have the appropriate kit. Ideally the standard DIY reflow oven project would probably be a useful example.
I do have an example project but its work in progress right now. I need to send the PCB gerbers off to SEEED. The only problem is when I open up the files I keep tweaking stuff ;)
Yes I can't see anything being used for 136years so I think we are safe LOL.
I am calling 'compute' from setInterval.
setInterval (function() { p.setInput(temp); p.compute(); }, 1000);
Has anyone used this javascript PID controller code? Everything looks good but I can't figure out how to call it. Can someone point me in the right direction?
I'm still trying to wrap my head around this 'prototype' concept in javascript. Yet to reach that ah ha moment!