Reputation: 19
I use an A/D converter to get some results of an electric conductivity probe. I use a miniEC interface from Sparky's Widgets. We run a calibration and get the slope and the intercept values. When I am testing this values with this calibration in a static script the result is correct.
See here, not a big thing but a proof that my calibration works well. The result is correct.
#!/usr/bin/perl
my $slope = "0.048684077307972626";
my $intercept = "24.831896523430906";
$ECdec = 62.5;
print "$ECdec \n";
###lin
$EC1 = ( ( $ECdec - $intercept ) / $slope );
print "Electric Conductivity $EC1 µS/m \n";
Output is:
62.5
Electric Conductivity 773.725323749752 �S/m
When I swap the static value $ECdec
to the output of the A/D Converter and try to get a result it is totally wrong. Can anyone see my failure?
Here is the Perl which reads the probes value from the converter, swap the bytes, convert it to decimal and then add the linear regression. What did I do wrong?
#!/usr/bin/perl
my $dir = '/var/www/motion';
my $slope = "0.048684077307972626";
my $intercept = "24.831896523430906";
###get value
my $EC = `sudo i2cget -y 1 0x4a 0x00 w` ;
print "$EC \n";
###swap
my $ECswap = $EC;
substr $ECswap, 4, 0, substr $ECswap, 2, 2, q();
print "$ECswap \n";
###convert to decimal
$ECdec = hex($ECswap);
print "$ECdec \n";
$ECvalue = ($ECdec - $ECintercept)/$slope);
print "$ECvalue"
#$rrd = `/usr/bin/rrdtool update $dir/homeec.rrd N:$ECdec`;
####system ("clear");
print "Electric Conductivity $ECdec µS/m \n";
Output here is:
0x5303
0x0353
851
Electric Conductivity 16969.9858590372 �S/m
Upvotes: 0
Views: 97
Reputation: 126722
You are printing $ECdec
in your output instead of $ECvalue
Also, please always post your real code. The program you have shown won't compile and is clearly not the one that is giving you problems
This is how your program should look
You must always use strict
and use warnings 'all'
at the top of even the most trivial Perl programs, and declare all of your variables with my
You should always use utf8
if your code contains non-ASCII characters like the Greek mu µ
in microSiemens. Perl doesn't support source code encoded other than in 7-bit ASCII or UTF-8. I don't know whether your terminal expects UTF-8 characters, and you may need to alter the use open
statement
I have commented out your call to i2cget to retrieve a real value and subsituted a constant string instead
I have also converted the hex string to binary before swapping the bytes for speed, but it's far from critical and you should retain the character swap if you find it more readable. I would use a regular expression and write it like this
die unless $EChex =~ /0x(\p{hex}{2})(\p{hex}{2})/;
my $EC = hex($2.$1);
#!/usr/bin/perl
use utf8;
use strict;
use warnings 'all';
use open qw/ :std :encoding(utf8) /;
use constant DIR => '/var/www/motion';
use constant SLOPE => 0.048684077307972626;
use constant INTERCEPT => 24.831896523430906;
# my $EChex = `sudo i2cget -y 1 0x4a 0x00 w` ;
my $EChex = '0x5303';
printf "\$EChex = %s\n", $EChex;
my $EC = hex $EChex;
printf "\$EC = %s\n", $EC;
$EC = (($EC & 0xFF00) >> 8) | (($EC & 0xFF) << 8); # swap bytes
my $ECvalue = ($EC - INTERCEPT) / SLOPE;
printf "Electric Conductivity %.3fµS/m \n", $ECvalue;
$EChex = 0x5303
$EC = 21251
Electric Conductivity 16969.986µS/m
Upvotes: 1