diff --git a/README_BuildProcess.md b/README_BuildProcess.md index 4ae1e651e..23f3e3363 100644 --- a/README_BuildProcess.md +++ b/README_BuildProcess.md @@ -117,7 +117,9 @@ This is a partial list of definitions that can be added in a `BOARD.py` file's ` * `DUMP_IGNORE_VARIABLES="...\0"` - string containing zero-terminated list of global variable names to ignore when `dump()` is called. Must be explicityly zero-terminated so there are 2 trailing 0s * `FSMC_BITBANG` - if using a built-in FSMC Graphics LCD, don't use the hardware but instead do it in software * `FLASH_64BITS_ALIGNMENT=1` - For testing 64 bit flash writes on linux -* `JSMODULESOURCES+=libs/.../foo.min.js` - include the given JS file as a module that can be used via `require("foo")` +* `JSMODULESOURCES+=libs/js/.../foo.min.js` - include the given JS file as a module that can be used via `require("foo")` + * `JSMODULESOURCES+=ModuleName:libs/js/.../module.min.js` - include as a module used with `require("ModuleName")` + * `JSMODULESOURCES+=_:libs/js/.../boot.min.js` - include as a file that's run at boot time * `JSVAR_MALLOC` - Allocate space for variables at jsvInit time, rather than statically * `JSVAR_FORCE_16_BYTE` - Force 16 byte JsVars (rather than packing bits to get JsVar size down to the minimum possible) * `USE_FONT_6X8=1` - Also include in a 6x8 fixed width bitmap font diff --git a/boards/CURIO.py b/boards/CURIO.py index a6b40db6e..11328cebc 100644 --- a/boards/CURIO.py +++ b/boards/CURIO.py @@ -80,6 +80,7 @@ 'INCLUDE += -I$(ROOT)/libs/misc', 'WRAPPERSOURCES += libs/misc/jswrap_curio.c', 'WRAPPERSOURCES += libs/joltjs/jswrap_qwiic.c', + 'JSMODULESOURCES += _:libs/js/misc/curio.js' ] } }; diff --git a/libs/js/misc/curio.js b/libs/js/misc/curio.js new file mode 100644 index 000000000..148020d36 --- /dev/null +++ b/libs/js/misc/curio.js @@ -0,0 +1,126 @@ +// see: +// libs/misc/jswrap_curio.c +// boards/CURIO.py +led([0,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0]); + +const PID = { + // gains + Pg : 0.015, + Ig : 0.001, + Dg : 0.05, + // min/max + Imin : -0.5, + Imax : 0.5 +}; +const CONST = { + MAXSPEED : 25, // steps/sec + MINSPEED : 15, // steps/sec - slowest we can sensibly run + SLOW_STEPS : 10, // how many steps before we slow down +}; +function Motor(M1,M2) { + Object.assign(this,{ + M1:M1,M2:M2, + aspeed : 0, // actual speed + rspeed : 0, // requested speed + duty : 0, + idle : 0, + lastTime : getTime(), // time of last pin event + pwm : undefined, // PWM pin + direction : 0, // 1 or -1 + odometer : 0, // how many steps have we moved? + // move to location + stepsLeft : 0, + stepSpeed : 0, // if set, we do a certain number of steps + // PID + err:0, + P:0,I:0,D:0, + }); +} +Motor.prototype.setSpeed = function(speed) { + if (speed==0) { + digitalWrite([this.M1,this.M2],0); + this.duty = 0; + this.rspeed = 0; + this.pwm = undefined; + this.P = this.I = this.D = this.err = 0; + } else { + if (speed>0) { + this.pwm = this.M1; + this.direction = 1; + } else if (speed<0) { + this.pwm = this.M2; + this.direction = -1; + } + this.duty = 1; + this.idle = 0; + analogWrite(this.pwm,this.duty); + } + this.rspeed = Math.abs(speed); +}; +Motor.prototype.moveSteps = function(steps, speed) { + if (!speed || speed<0) speed = CONST.MAXSPEED; + if (steps<1) { + this.setSpeed(-speed); + } else { + this.setSpeed(speed); + } + this.stepSpeed = speed; + this.stepsLeft = Math.abs(steps); +}; +Motor.prototype.onSensor = function(e) {"ram"; + var d = e.time-this.lastTime; + if (d<0.02) return; + //print(d.toFixed(3)); + this.lastTime = e.time; + this.odometer += this.direction; + if (this.stepsLeft) this.stepsLeft--; + this.aspeed = this.aspeed*0.6 + (0.4/d); + //print(this.aspeed, this.lastTime, this.idle); + this.idle=0; +}; +Motor.prototype.onStep = function() {"ram"; + this.idle++; + if (this.idle>10) + this.aspeed = this.aspeed*0.6 + (0.4 / (getTime()-this.lastTime)); + // Stepping + if (this.stepSpeed) { + if (this.stepsLeft >= CONST.SLOW_STEPS) { + this.rspeed = this.stepSpeed; + } if (this.stepsLeft) { + this.rspeed = ((this.stepSpeed * this.stepsLeft / CONST.SLOW_STEPS) + CONST.MINSPEED) / 2; + } else { + this.stepSpeed = 0; + this.setSpeed(0); + // complete! + } + } + // PID + var err = this.rspeed-this.aspeed; + this.P = this.err * PID.Pg; + this.D = (err-this.err) * PID.Dg; + this.err = err; + this.I = E.clip(this.I + err * PID.Ig, PID.Imin, PID.Imax); + this.duty = E.clip(0.5 + this.P + this.I + this.D, 0, 1); + if (this.pwm) + analogWrite(this.pwm, this.duty); +}; + +L = new Motor(ML1,ML2); +R = new Motor(MR1,MR2); +setInterval(function() {"ram"; + L.onStep(); + R.onStep(); +}, 20); +clearWatch(); +setWatch(L.onSensor.bind(L), IRL, {repeat:true, edge:0}); +setWatch(R.onSensor.bind(R), IRR, {repeat:true, edge:0}); + +function go(l,r) { + L.setSpeed(l); + R.setSpeed(r); +} +function move(l,r,lspeed,rspeed) { + L.moveSteps(l,lspeed); + R.moveSteps(r,rspeed); +} +