**A Object to Calibrate and Scale Analog Inputs to Engineering Units( In three installments)
Part 3:
**
Let’s add two fields to the calibration file, name and units.
var AnalogReadObj1={
calibrations:[
{name:"Inlet",units:"psig",pin:'A0',slope:10.0,Intercept:5.0},
{name:"Outlet",units:"psig",pin:'A1',slope:50.0,Intercept:-25.0},
{name:"Motor",units:"Amps",pin:'A2',slope:1.0,Intercept:0.0},
{name:"Supply",units:"Volts",pin:'A3',slope:1.0,Intercept:0.0},
{name:"Flow",units:"Liters/minute",pin:'A4',slope:1.0,Intercept:0.0}
]
};//end AnalogReadObj1
function saveCalibration(calibration) {
var Q;
var sss=JSON.stringify(calibration);
if (Q===undefined) {
Q = E.openFile("Mycalibrations.cal", "w");
Q.write(sss);
Q.close();
Q = undefined;
}//endif
}//end doLog
saveCalibration(AnalogReadObj1);
console.log(require("fs").readFileSync("Mycalibrations.cal"));
The code that knits the two objects together and implements a two point calibration.
The calibration is save to the calibration file on the SD card followed by the reading of the calibrated analog inputs in engineering units (EU).
Button 1 on the Espruino board is used to step through the steps. Entering A= selects the channel to calibrate. During the calibration entering B= is used to set the EU values needed for calibration. If A=-1 exits calibration, and proceeds to reading the analog inputs after each press of button1.
var sss=(require("fs").readFileSync("Mycalibrations.cal"));
//console.log(sss);
//The constructor for AnalogReadObj
function AnalogReadObj(ARO){
this.A=JSON.parse(ARO);
}//end AnalogReadObj
//Methods for AnalogReadObj
AnalogReadObj.prototype.saveCalibration=function() {
var Q;
var sss=JSON.stringify(this.A);
console.log("Saving calibrations");
console.log(this.A);
if (Q===undefined) {
Q = E.openFile("Mycalibrations.cal", "w");
Q.write(sss);
Q.close();
Q = undefined;
}//endif
};//saveCalibration
AnalogReadObj.prototype.SanalogRead=function(Arg){
for(var i=0;i in this.A.calibrations;i++){
// console.log(i,Arg,this.A.calibrations[i].pin);
if(Arg===this.A.calibrations[i].pin){
return( analogRead(Arg)*this.A.calibrations[i].slope+this.A.calibrations[i].Intercept);
}//endif
}//next i
return -99;
};//end SanalogRead
AnalogReadObj.prototype.getName=function(Arg){
for(var i=0;i in this.A.calibrations;i++){
// console.log(i,Arg,this.A.calibrations[i].pin);
if(Arg===this.A.calibrations[i].pin){
return( this.A.calibrations[i].name);
}//endif
}//next i
return -99;
};//end SanalogRead
AnalogReadObj.prototype.getUnits=function(Arg){
for(var i=0;i in this.A.calibrations;i++){
// console.log(i,Arg,this.A.calibrations[i].pin);
if(Arg===this.A.calibrations[i].pin){
return( this.A.calibrations[i].units);
}//endif
}//next i
return -99;
};//end SanalogRead
AnalogReadObj.prototype.SetAnalog=function(Arg){
for(var i=0;i in this.A.calibrations;i++)
pinMode(this.A.calibrations[i].pin, 'analog');
};//end SetAnalog
//end methods for AnalogReadObj
//The constructor for LinRegObj
function LinRegObj(a,nn){
this.Sx=0;
this.Sy=0;
this.Sxy=0;
this.Sxx=0;
this.Syy=0;
this.N=0;
this.A=a;
this.NN=nn;
this.slope=0;
this.intercept=0;
}//end LinRegObj
//Methods for LinRegObj
LinRegObj.prototype.TakeData=function(y){
//LinRegObj.prototype.TakeData=function(x,y){
for(i=0;i<this.NN;i++){
var x=analogRead(this.A.pin);
this.Sx+=x;
this.Sy+=y;
this.Sxy+=(x*y);
this.Sxx+=(x*x);
this.Syy+=(y*y);
this.N++;
}//next i
};//endTakeData
LinRegObj.prototype.Calculate=function(){
this.slope=(this.N*this.Sxy-this.Sx*this.Sy)/
(this.N*this.Sxx - this.Sx*this.Sx);
this.intercept=this.Sy/this.N-(this.slope*this.Sx)/this.N;
this.A.slope=this.slope;
this.A.Intercept=this.intercept;
};//end Calculate
LinRegObj.prototype.ListChannels=function(T){
for(var i=0;i in T;i++){
console.log(i,","+T[i].name+","+T[i].units);
}//next i
};//end List Channels
//end LinRegObj methods
var A=0;//used to select channel -1 exits calibration sequence
var B=0;//used to input EU values during calibration
//create an instance of AnalogReadObject using the string data contained in
//the variable sss
var ScaledAR=new AnalogReadObj(sss);
//console.log(ScaledAR.calibrations);
// setup the pins for analog
ScaledAR.SetAnalog();
//test example calculation
var Q=new LinRegObj(ScaledAR.A.calibrations[0],5);// 5 samples to take
//SelectChannel();
console.log("Press button on Espruino board to start");
var state=10;
function doButton(){
if (digitalRead(BTN1) === 1){
switch (state){
case 10:
Q.ListChannels(ScaledAR.A.calibrations);
console.log(' ');
console.log("Select channel by number");
console.log("Type A=<number>; in left pane");
console.log("Type A=-1; in the left pane to exit calibrations");
console.log("Then press button on Espruino board");
console.log(' ');
state=20;
break;
case 20:
if(A<0){
console.log("Exit");
ScaledAR.saveCalibration();
state=200;
return;
}
if(A in ScaledAR.A.calibrations){
console.log("Calibrating ",ScaledAR.A.calibrations[A].name);
console.log("Apply low value (0.0) input to sensor");
console.log("Enter the engineering units (EU) by typing in left pane");
console.log("B=<EU>;");
console.log("Then press button on the Espruino board");
}//endif A in Q
state=30;
break;
case 30:
Q.TakeData(B);
console.log("Calibrating ",ScaledAR.A.calibrations[A].name);
console.log("Apply high value (80% FS) input to sensor");
console.log("Enter the engineering units (EU) by typing in left pane");
console.log("B=<EU>;");
console.log("Then press button on the Espruino board");
state=40;
break;
case 40:
Q.TakeData(B);
Q.Calculate();
console.log("Calibrating ",ScaledAR.A.calibrations[A].name);
console.log("Slope= ",Q.slope);
console.log("Intercept= ",Q.intercept);
console.log("Press button on the Espruino board");
state=10;
break;
case 200:
console.log(' ');
// Now do a scaled read of pin A0
console.log(ScaledAR.getName('A0')," A0= ",ScaledAR.SanalogRead('A0').toFixed(2)+" ",ScaledAR.getUnits('A0'));
// Now do a scaled read of pin A1
console.log(ScaledAR.getName('A1')," A1= ",ScaledAR.SanalogRead('A1').toFixed(2)+" ",ScaledAR.getUnits('A1'));
// Now do a scaled read of pin A2
console.log(ScaledAR.getName('A2')," A2= ",ScaledAR.SanalogRead('A2').toFixed(2)+" ",ScaledAR.getUnits('A2'));
// Now do a scaled read of pin A3
console.log(ScaledAR.getName('A3')," A3= ",ScaledAR.SanalogRead('A3').toFixed(2)+" ",ScaledAR.getUnits('A3'));
// Now do a scaled read of pin A4
console.log(ScaledAR.getName('A4')," A4= ",ScaledAR.SanalogRead('A4').toFixed(2)+" ",ScaledAR.getUnits('A4'));
console.log("Press button on Espruino board");
return;
default:
}//end switch
}//end BTN1
}//end doButton
setWatch(doButton, BTN1, true);
The left pane view:
Press button on Espruino board to start
=undefined
0 ,Inlet,psig
1 ,Outlet,psig
2 ,Motor,Amps
3 ,Supply,Volts
4 ,Flow,Liters/minute
Select channel by number
Type A=<number>; in left pane
Type A=-1; in the left pane to exit calibrations
Then press button on Espruino board
A=0;
Calibrating Inlet
Apply low value (0.0) input to sensor
Enter the engineering units (EU) by typing in left pane
B=<EU>;
Then press button on the Espruino board
>B=0;
=0
Calibrating Inlet
Apply high value (80% FS) input to sensor
Enter the engineering units (EU) by typing in left pane
B=<EU>;
Then press button on the Espruino board
>B=80;
=80
Calibrating Inlet
Slope= 100.13897386465
Intercept= -0.03419722673
Press button on the Espruino board
0 ,Inlet,psig
1 ,Outlet,psig
2 ,Motor,Amps
3 ,Supply,Volts
4 ,Flow,Liters/minute
Xxxxxxxxxxxxxxxxxxxx
A=-1; exits the calibration sequence.
Xxxxxxxxxx
>A=-1
=-1
Exit
Saving calibrations
{
"calibrations": [
{
"name": "Inlet",
"units": "psig",
"pin": "A0",
"slope": 100.13897386465, "Intercept": -0.03419722673 },
{
"name": "Outlet",
"units": "psig",
"pin": "A1",
"slope": 50, "Intercept": -25 },
{
"name": "Motor",
"units": "Amps",
"pin": "A2",
"slope": 1, "Intercept": 0 },
{
"name": "Supply",
"units": "Volts",
"pin": "A3",
"slope": 1, "Intercept": 0 },
{
"name": "Flow",
"units": "Liters/minute",
"pin": "A4",
"slope": 1, "Intercept": 0 }
]
}
Inlet A0= 79.94 psig
Outlet A1= 12.00 psig
Motor A2= 0.72 Amps
Supply A3= 0.69 Volts
Flow A4= 0.82 Liters/minute
Press button on Espruino board
Testing was performed using five 1k resistors wired in series. One end connects to GND and the other end to +3.3V pins. A wire from the analog input pin can then be connected to connections along the resistor chain.
Espruino is a JavaScript interpreter for low-power Microcontrollers. This site is both a support community for Espruino and a place to share what you are working on.
**A Object to Calibrate and Scale Analog Inputs to Engineering Units( In three installments)
Part 3:
**
Let’s add two fields to the calibration file, name and units.
The left screen:
The code that knits the two objects together and implements a two point calibration.
The calibration is save to the calibration file on the SD card followed by the reading of the calibrated analog inputs in engineering units (EU).
Button 1 on the Espruino board is used to step through the steps. Entering A= selects the channel to calibrate. During the calibration entering B= is used to set the EU values needed for calibration. If A=-1 exits calibration, and proceeds to reading the analog inputs after each press of button1.
The left pane view:
Testing was performed using five 1k resistors wired in series. One end connects to GND and the other end to +3.3V pins. A wire from the analog input pin can then be connected to connections along the resistor chain.
2 Attachments