-
@tage Hi, I implemented your example code and wow, my readings have stabilized quite nicely. I also tweaked the code to get degrees Celsius and degrees Fahrenheit. My original code was returning a temperature of about 80 F, but that was with only 20 samples. Now I am taking 200 samples every 3 seconds and the temp using the new code is at approximately
Temp: 77.86076511596 Fixed Temp: 77.9
which I understand is due to usingtoFixed(1)
The more samples that I take the 'more accurate' my readings become. I wonder how many samples I can take before I notice a lag between readings.@Manxome Thank you for your code recommendations. Accuracy for the temp sensor is:
± 1°CI checked my room thermostat and it says 77 F and my temp sensor says 78.1 so it's 'not off by much'. The sensor is encapsulated in epoxy and a stainless steal tube which is probably the cause of the 1 degrees difference.
Code:
function CompareForSort(a,b) { if (a == b) return 0; if (a < b) return -1; else return 1; } function MedianRead(n, tempType) { var myarr = []; for(i=0; i<n; i++){ var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao var vZero = 0.4; var tCoeff = 19.5 / 1000; var tempinc = (vOut - vZero) / tCoeff; var tempinf = tempinc * (9 / 5) + 32; switch(tempType) { case 'c': myarr[i] = tempinc; break; case 'f': myarr[i] = tempinf; break; default: myarr[i] = tempinc; } } //console.log(myarr); myarr.sort(CompareForSort); myarr.splice(n-2,2); myarr.splice(0,2); //console.log(myarr); m=myarr.length; var sum=myarr.reduce(function(a,b) { return a+b; }); var temp = sum/m; var tempFixed = temp.toFixed(1); console.log("Temp: " + temp + " Fixed Temp: " + tempFixed); console.log(tempFixed); } var ph = new Sensor("ph", 0x63); var phDisplay = new s7s("ph", 0x71); var resTempDisplay = new s7s("res", 0x40); setInterval(function (e) { //var t = getResTempValue(100, 'C'); MedianRead(200, 'f'); //resTempDisplay.sendValue(t, "c"); //console.log(t); }, 3000);
-
doh! I used brackets instead of parentheses.
data.charAt(i);
works.Code:
s7s.prototype.sendValue = function (data) { var a = this.address; var clr = this.displayTable.Clear; //Display clear command var dpc = this.displayTable.dp.cmd; //Decimal point command var dplo = this.displayTable.dp.location; //Decimal point location map var i; var length = data.length; var dpLoc; var value = ""; for(i=0; i<length; i++) { var char = data.charAt(i); if(char != ".") { value += char; } if(char == ".") { dpLoc = i; } } I2C1.writeTo(a, clr); //Clear display I2C1.writeTo(a, value); if(typeof dpLoc !== 'undefined') { I2C1.writeTo(a, dpc); I2C1.writeTo(a, dplo[dpLoc - 1]); } };
-
-
I am not sure why I am receiving undefined when I loop through data which is a string, To see if data contained a string I did console.log(typeof data + ": " + data); which echoed out String : 26.19. From my understanding, I thought looping through the data string and using charAt[i] I should in theory return the character at i, however, I am receiving undefined. Why is that and how do I return the character at i?
s7s.prototype.sendValue = function (data) { var a = this.address; var length = data.length; var i; var val; var dpLoc; console.log(typeof data + ": " + data); //echos out a string for(i=0; i<data.length; i++) { var char = data.charAt[i]; console.log(data.charAt[i]); if(char != ".") { val += char; } if(char == ".") { dpLoc = i; } } //console.log(val); //I2C2.writeTo(a, value); };
-
Code that I threw together to get decimal places to work. It looks a bit rough, but it seems to work.
function s7s (sensor, theAddress) { this.displayFor = sensor; this.address = theAddress; this.displayTable = { "Clear" : 0x76, "dp" : { "cmd" : 0x77, "location" : [ 0b00000001, //Digit 0 0b00000010, //Digit 1 0b00000100, //Digit 2 0b00001000 //Digit 3 ] } }; } setInterval(function (e) { ph.getSensorResult(function(value) { var toChar = ""; var a = phDisplay.address; var clr = phDisplay.displayTable.Clear; //Display clear command var dpc = phDisplay.displayTable.dp.cmd; //Decimal point command var dplo = phDisplay.displayTable.dp.location; //Decimal point location map var i; I2C1.writeTo(a, clr); //Clear display if(value[0] === 1) { for(i=0; i<value.length; i++) { if (value[i] !== 1 && value[i] !== 0) { var c = String.fromCharCode(value[i]); if (c != '.') { toChar += c; } if (c == '.') { var n = i - 2; I2C1.writeTo(a, dpc); I2C1.writeTo(a, dplo[n]); } if (i == (value.length - 2)) { console.log(toChar); I2C1.writeTo(a, toChar); toChar=""; } } } } }); }, 2000);
-
@Manxome Hi,
Datasheet can be found at: http://www.atlas-scientific.com/product_pages/probes/env-tmp.html? I haven't tried the code yet, but will (hopefully tonight). I am packing and getting ready to move by next weekend. I'm keeping my project unpacked until the last minute :). As soon as I test your code and @tage code I will reply back.Taking a second look at my code, inside the switch I should of wrote:
temp += tempinc; And temp += tempinf
-
-
-
I'm still struggling to get MCP9701 temp sensor to work efficiently. I believe my calculations are off or possibly the leads on the sensor are too long causing interference and unreliable readings. My goal is to get my temp readings stable and return either the temp in degrees C or degrees F which will be chosen by setting a 'c' or 'f' in the functions arguments.
Also, I am attempting to stabilize the readings by using a for loop to return the average temp. I recently changed my code around to include a switch statement to return the temp in degrees C or degrees F which is where I think I did something wrong.
code:
function getResTempValue(x, tempType) { var temp=0; var avgTemp=0; var tfixed=0; for (var i=0;i<x;i++) { var vOut = E.getAnalogVRef() * analogRead(A0); // if you attached VOUT to Ao var vZero = 0.4; var tCoeff = 19.5 / 1000; var tempinc = (vOut - vZero) / tCoeff; var tempinf = tempinc * (9 / 5) + 32; switch(tempType) { case 'c': temp = tempinc; break; case 'f': temp = tempinf; break; default: temp = tempinc; //code block } } temp = temp / x; tfixed = temp.toFixed(2); return tfixed; } setInterval(function (e) { var t = getResTempValue(10, 'f'); var toChar = ""; var a = resTemptDisplay.address; var clr = resTemptDisplay.displayTable.Clear; //Display clear command var dpc = resTemptDisplay.displayTable.dp.cmd; //Decimal point command var dplo = resTemptDisplay.displayTable.dp.location; //Decimal point location map var i; I2C1.writeTo(a, clr); //Clear display I2C1.writeTo(a, t); console.log(t); }, 2000);
-
@Gordon Congratulations on your success!
-
-
@Gordon I updated my pledge to the Ultimate Toy Kit Backer :-) I changed my credit card info to my paypal Credit card. I hope there are no issues with paypal and the exchange rate. If there is, can you send me a paypal money request for Paypal Credit?
-
Everything seems to be functioning quite nicely :-) Now all I need to do is make an object of the functionality and placements of the decimal points. I'll post back in a few days with the code. @allObjects I will for sure read over your post from earlier.
-
@DrAzzy @allObjects thank you for the explanations
Sorry, I'm a bit dyslexic at times :) I meant to write 0b00000001
-
-
My project consists of espruino, environment sensors and 4 blue 7 segment displays
Datasheet(specifically decimals): https://github.com/sparkfun/Serial7SegmentDisplay/wiki/Special-Commands#decimal
What I would like to accomplish is send data, for an example send the room temp, i.e. 76.7F to the 7-segment display. Depending on where the decimal place is, turn on that decimal which I dont think is that hard to do. What I am struggling with is calculating the bytes to send in order to turn on the specific decimal.
To better understand this i will use the github totorial for my example. For example, To turn on the colon, apostrophe, and far-right decimal point we need to set bits 4, 5, and 3, respectively. Our data byte will therefore be: 0b00111000 (ie. hex 0x38, or decimal 56).
From experience, I know the 0b signifies the data following is in binary format and 00111000 equals 56. Where did the 56 come from? There's a handy chart explaining the bit layout, however I still don't understand.
-
Hi @Gordon The reason why I chose
Sensor.prototype = {
was, at the time, I didn't care for the repetitiveness of writingSensor.prototype.
However, thats nothing that copy and paste can't fix :). As you recommended, I switched toSensor.prototype.getSensorType = function
. I can appreciate the readability and the code seems to flow a little better and makes sense to me. -
-
-
-
Hi, my question kind of relates to my question from: generic pause/wait? I'm trying to wrap my head around how prototypeing works. does the Espruino support bind? For example:
setTimeout(function (e) { this.getSensorReading(); }.bind(this), w); //Attempting to execute getSensorReading()
I receive error:
Uncaught Error: Function "bind" not found! at line 8 col 58 ...this.getSensorReading(); }.bind(this), w); //Attempting to e... ^ in function "getSensorResult" called from line 1 col 20 ph.getSensorResult();
-
@allObjects I appologize for not explaining myself.
For example I execute:
I2C1.writeTo(0x63, "R,25.3");
That tells the ph sensor to calculate the ph at the temp 25.3C. The ph sensor will take 1 second to calculate the ph, therefor, I will be required to wait 1 second before executing:
I2C1.readFrom(0x63, 7);
So depending on the specific command that i invoke will be require to wait what ever the wait value is before I readFrom the sensor. I hope I did a better job at explaining...
When you said:
What I understand so far is that you have the following system and
process: The system[Sys] reads[read] temperatures[temp] with
temperature sensors[Tempsensor], ph values[ph] with ph sensors, etc.
The readings[tmp,ph,etc.] are then somehow displayed, transmitted, or
made available otherwise for user or other system consummation.
Reading and follow up processing are repeated based on some kind of
schedule.Yes, I am gathering all the sensor data and will eventually send all the calculations to my Intel Edison using UART communication; also out put all the values to 4x 4digit 7-segment displays.
Maybe a better example? :
Sensor.prototype = { constructor: Sensor, getSensorType:function () { return this.type; //Get Sensor type }, getSensorAddress:function () { return this.address; //Get Sensor address }, getSensorReading:function() { a = this.getSensorAddress; d = I2C1.readFrom(a, 7); return d; }, getSensorResult:function () { var a = this.getSensorAddress; var c = this.cmdTable.Reading.R.cmd; var w = this.cmdTable.Reading.R.wait; var that = this; I2C1.writeTo(a, c); setTimeout(function (e) { that.getSensorReading(); }, w); }, storeSensorResult:function () { }, updateResTemp:function (temp) { console.log("Before: " + this.cmdTable.Reading.R.cmd); this.cmdTable.Reading.R.cmd = "R," + temp; console.log("After: " + this.cmdTable.Reading.R.cmd); } }; var ph = new Sensor("ph", 0x63); ph.updateResTemp(90.5); ph.getSensorResult();
That last example doesn't exactly work. I receive the error:
Uncaught Error: Function "getSensorReading" not found! at line 1 col 8 { this.getSensorReading(); } ^ in function called from system
How do I call getSensorReading() function from Sensor.prototype?
I updated my code to my working code. -
@allObjects So far I have:
I2C1.setup({scl:b6, sda:b7}); function Sensor (theType, theAddress) { this.type = theType; //i.e. PH this.address = theAddress; //i2c Address this.sensorResult = 0; //Store sensor result this.cmdTable = { 'Calibrate' : { //List of Calibration commands and timeout value. "clear" : { "cmd" : "Cal,Clear", "wait" : 300 }, "mid" : { "cmd" : "Cal,mid,7.00", "wait" : 1300 }, "low" : { "cmd" : "Cal,low,4.00", "wait" : 1300 }, "high" : { "cmd" : "Cal,high,10.00", "wait" : 1300 }, "query" : { "cmd" : "Cal,?", "wait" : 300 } }, 'Information' : { //Device Information }, 'LED' : { //Enable / Disable or Query the LEDs "L0" : { "cmd" : "L,0", "wait" : 300 }, "L1" : { "cmd" : "L,1", "wait" : 300 }, "L?" : { "cmd" : "L,?", "wait" : 300 } }, 'Reading' : { //Takes a single reading "R" : { "cmd" : "R,?", "wait" : 1000 } //Takes a single temperature compensated reading }, 'Serial' : { //Switch back to UART mode }, 'Sleep' : { //Enter low power sleep mode }, 'Status' : { //Retrieve status information }, 'Temperature' : { //Set or Query the temperature compensation "T" : { "cmd" : "T,19.5", "wait" : 300 }, //Where the temperature is any value; floating point, or int, in ASCII form "T?" : { "cmd" : "T,?", "wait" : 300 } //Query the set temerature }, 'Factory' : { //Factory reset }, }; } Sensor.prototype = { constructor: Sensor, getSensorType:function () { return this.type; //Get Sensor type }, getSensorAddress:function () { return this.address; //Get Sensor address }, getSensorResult:function () { //I2C1.read }, storeSensorResult:function () { }, updateResTemp:function (temp) { var reading = cmdTable.Reading.R.cmd; reading = "R," + temp; Console.log(reading); } }; var ph = new Sensor("ph", 0x63); ph.updateResTemp(90.5);
Is that what you are refering too? I am new to Javascript objects and etc... For example, in order for me to get the sensor result I would invoke getSensorResult and grab the values from the cooresponding Sensor object and setTimeout to whatever the wait value is of the specific cmd?
Also, to take a Reading in i2c I am required to pass the temperature along with the R to get a temperature compensated result. I have the default command as R,19.5. How would I update the cmd to the newely taken temperature value? I tried to change the value and I receive the following error:
Uncaught Error: Field or method does not already exist, and can't
create it on undefined at line 2 col 27var reading = cmdTable.Reading.R.cmd; e ^ in function "updateResTemp" called rom line 1 col 22
ph.updateResTemp(90.5);
I fixed the error
new and complete code:I2C1.setup({scl:b6, sda:b7}); function Sensor (theType, theAddress) { this.type = theType; //i.e. PH this.address = theAddress; //i2c Address this.sensorResult = 0; //Store sensor result this.cmdTable = { "Calibrate" : { //List of Calibration commands and timeout value. "clear" : { "cmd" : "Cal,Clear", "wait" : 300 }, "mid" : { "cmd" : "Cal,mid,7.00", "wait" : 1300 }, "low" : { "cmd" : "Cal,low,4.00", "wait" : 1300 }, "high" : { "cmd" : "Cal,high,10.00", "wait" : 1300 }, "query" : { "cmd" : "Cal,?", "wait" : 300 } }, "Information" : { //Device Information }, "LED" : { //Enable / Disable or Query the LEDs "L0" : { "cmd" : "L,0", "wait" : 300 }, "L1" : { "cmd" : "L,1", "wait" : 300 }, "L?" : { "cmd" : "L,?", "wait" : 300 } }, "Reading" : { //Takes a single reading "R" : { "cmd" : "R,?", "wait" : 1000 } //Takes a single temperature compensated reading }, "Serial" : { //Switch back to UART mode }, "Sleep" : { //Enter low power sleep mode }, "Status" : { //Retrieve status information }, "Temperature" : { //Set or Query the temperature compensation "T" : { "cmd" : "T,19.5", "wait" : 300 }, //Where the temperature is any value; floating point, or int, in ASCII form "T?" : { "cmd" : "T,?", "wait" : 300 } //Query the set temerature }, "Factory" : { //Factory reset }, }; } Sensor.prototype = { constructor: Sensor, getSensorType:function () { return this.type; //Get Sensor type }, getSensorAddress:function () { return this.address; //Get Sensor address }, getSensorResult:function () { //I2C1.read }, storeSensorResult:function () { }, updateResTemp:function (temp) { console.log("Before: " + this.cmdTable.Reading.R.cmd); //reading; //reading = "R," + temp; //Console.log(reading); this.cmdTable.Reading.R.cmd = "R," + temp; console.log("After: " + this.cmdTable.Reading.R.cmd); } }; var ph = new Sensor("ph", 0x63); ph.updateResTemp(90.5);
-
No, results don't always have to return in a decimal format, however, in this case they will. I have
if(typeof dpLoc !== 'undefined')
For the moments where I wont, for example, taking a PPM reading of a solution. That was my attempt to write a generic function to output a result to my 4 - digit 7 segment display.