Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. ====== Embedded Linux computer with 1-wire net ====== Linksys NSLU2 running Debian Linux off of flash memory, polls a 1-wire net every 5 minutes and records the data (temperature and humidity) to a remote SQL server. 1-Wire ===== PIC18 Microcontroller ===== PIC18F4523 reading an ADT7410 temperature sensor via I2C. ===== Web box on main page ===== Displays the following little info box about temperature, humidity, and atmospheric pressure. <box><php>include("webinfo.php");</php></box> ===== Files ===== ==== ADT7410.asm ==== <file mpasm ADT7410.asm> list p=18f4523 include <P18f4523.INC> GLOBAL INIT_I2C,READ_ID,READ_TEMP,Therm ; EXTERN SendChar #DEFINE ADDRESS_W 0x90 ; ADT7410 Address 0x48 shifted left by 1 #DEFINE ADDRESS_R 0x91 #DEFINE ADT7410_TEMPH 0x00 #DEFINE ADT7410_TEMPL 0x01 #DEFINE ADT7410_STATUS 0x02 #DEFINE ADT7410_CONFIG 0x03 #DEFINE ID 0x0B ; Obtain ID UDATA Temp RES 1 Therm RES 2 MyID RES 1 I2C_START MACRO BSF SSPCON2,SEN BTFSC SSPCON2,SEN GOTO $-2 ENDM I2C_STOP MACRO BSF SSPCON2,PEN BTFSC SSPCON2,PEN GOTO $-2 ENDM I2C_ACKCONF MACRO ; Confirm ACK BTFSC SSPCON2,ACKSTAT GOTO $-2 ENDM I2C_SendAck MACRO BSF SSPCON2,ACKEN BTFSC SSPCON2,ACKEN GOTO $-2 ENDM I2C CODE INIT_I2C ; BSF LATD,RD0 MOVLW 0x03 MOVWF SSPADD ; Baud Rate BSF TRISC,SDA ;Serial data (SDA) RC4/SDI/SDA BSF TRISC,SCL ;Serial clock (SCL) RC3/SCK/SCL BSF SSPSTAT,SMP BCF SSPSTAT,CKE MOVLW b'00001000' MOVWF SSPCON1 BSF SSPCON1,SSPEN I2C_START ; Send Start Bit ; Send Address for Write MOVLW ADDRESS_W MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK MOVLW ADT7410_CONFIG MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send Address for Write MOVLW b'11000000' MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send Stop I2C_STOP RETURN READ_ID I2C_START ; Send Start Bit ; Send Address for Write MOVLW ADDRESS_W MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send ID Byte MOVLW ID MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send Repeated Start Bit BSF SSPCON2,RSEN BTFSC SSPCON2,RSEN GOTO $-2 ; Send Address for Read MOVLW ADDRESS_R MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Receive Data BSF SSPCON2,RCEN BTFSC SSPCON2,RCEN GOTO $-2 MOVFF SSPBUF,MyID BSF SSPCON2,ACKDT ; NoAck for no more data I2C_SendAck ; Send Stop I2C_STOP RETURN READ_TEMP I2C_START ; Send Start Bit ; Send Address for Write MOVLW ADDRESS_W MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send ID Byte MOVLW ADT7410_TEMPH MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Send Repeated Start Bit BSF SSPCON2,RSEN BTFSC SSPCON2,RSEN GOTO $-2 ; Send Address for Read MOVLW ADDRESS_R MOVWF SSPBUF BTFSC SSPSTAT,BF GOTO $-2 I2C_ACKCONF ; Confirm ACK ; Receive Data BCF SSPCON2,ACKDT ; Ack for more data BSF SSPCON2,RCEN BTFSC SSPCON2,RCEN GOTO $-2 MOVFF SSPBUF,Therm+1 I2C_SendAck BSF SSPCON2,ACKDT ; NoAck for no more data BSF SSPCON2,RCEN BTFSC SSPCON2,RCEN GOTO $-2 MOVFF SSPBUF,Therm I2C_SendAck ; Send Stop I2C_STOP BCF LATD,RD0 RETURN END </file> ==== Pic18poller.pl ==== <file perl Pic18poller.pl> #!/usr/bin/perl use Device::SerialPort; use DBI; # MySQL CONFIG VARIABLES $host = "hostname"; $database = "database"; $tablename = "pic"; $user = "username"; $pw = "password"; #Filename for when MySQL server is offline $file="pcontroller_cache.dat"; # Set up the serial port # 19200, 81N on the USB ftdi driver my $port = Device::SerialPort->new("/dev/ttyUSB0"); $port->databits(8); $port->baudrate(19200); $port->parity("none"); $port->stopbits(1); $port->read(255); $port->write("\$S1,Q#"); my $notFndCnt = 0; $data=""; while($data !~ /\$C0.*\#/) { $data.=$port->read(255); } $port->close(); @values=split(/,/,$data); $hex=$values[3]; $Temperature=hex($hex)/128; #if(!$hex) { #die(); #} print "$Temperature\n"; my ($s,$m,$h,$d,$mon,$yr,$wday,$yday,$isdst) = localtime time; if($dbh = DBI->connect('DBI:mysql:'.$database.":$host",$user,$pw)) { $sql = "INSERT INTO `1wire`.`$tablename` (`dt`, `hex`, `temp_c`, `misc`) VALUES (CURRENT_TIMESTAMP, \'$hex\', \'$Temperature\', NULL);"; $c = $dbh->do($sql); if(!$quiet) {print "Affected $c rows for table $tablename\n";} $dbh->disconnect(); } else { if(!$quiet) {print "Could not connect to database: $DBI::errstr";} $c=0; } if(!$c) { if(!$quiet) {print "Failure, writing to $file\n";} $stamp = sprintf("%4d-%02d-%02d %02d:%02d:%02d", $yr+1900, $mon+1, $d, $h, $m, $s); open(FH,">>$file") || die("Cannot open $file."); print FH "$tablename,$stamp,$hex,$Temperature,0\n"; close(FH); } </file> ==== pic.php ==== <file php pic.php> <? # Jeff Brown # November 1th, 2010 # Version: 2.3 # http://photonicsguy.ca/nslu2 header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1 header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past date_default_timezone_set("America/Toronto"); include('config.inc.php'); $INTERVAL=2; $TZoffset=-3600*4; $link = mysql_connect($MYSQL_HOST,$MYSQL_USER,$MYSQL_PASS); if (!$link) { echo "Unable to connect to DB: " . mysql_error(); exit; } if (!mysql_select_db($MYSQL_DB)) { echo "Unable to select mydbname: " . mysql_error(); exit; } plot_picdata(); header('Content-Type: image/jpeg'); $file=$datadir."pic.gnuplot"; $fp=fopen($file,'w'); $tfrom=time()+$TZoffset-($INTERVAL*24*3600); $tto=(time()+$TZoffset); #Blackberry size: 480,360 $plot='set terminal jpeg nocrop size 1000,800 set xdata time set timefmt "%s" #set format x "%d/%m\n%I:%M" set format x "%a %d\n%I:%M %p" set grid nopolar set grid xtics mxtics ytics mytics noztics nomztics \ nox2tics nomx2tics noy2tics nomy2tics nocbtics nomcbtics #set grid layerdefault linetype 0 linewidth 1.000, linetype 0 linewidth 1.000 set key inside right bottom vertical Right noreverse enhanced autotitles box set title "'.date("F j, Y, g:i a").'" #set style data fsteps #set xlabel "Date\nTime" #TZoffset='.$TZoffset.' #set xrange ["'.$tfrom.'":"'.$tto.'"] noreverse nowriteback set ylabel "Temperature" #set yrange ['.$YRANGE.'] set yrange [0:30] #set xtics 1*3600 #set mxtics 4 #set mytics 1 plot \'data/_sql_pic.dat\' using 1:2 t \'PIC\' with lines lw 2'; $t=',\ \'data/_sql_3.dat\' using 1:2 t \'Sensor 1\' with lines lw 1,\ \'data/_sql_3.dat\' using 1:2 t \'Sensor 2\' with lines lw 1,\ \'data/_sql_3.dat\' using 1:2 t \'Sensor 3\' with lines lw 1 '; fwrite($fp,$plot); fclose($fp); passthru($gnuplot.' '.$datadir.'pic.gnuplot'); function plot_picdata() { global $datadir; global $INTERVAL; global $TZoffset; $file=$datadir."_sql_pic.dat"; $fp=fopen($file,'w'); $sql="SELECT UNIX_TIMESTAMP(`dt`),`temp_c` FROM `pic` WHERE 1 AND `dt`> DATE_SUB(NOW(),INTERVAL $INTERVAL DAY) ORDER BY `dt` ASC"; # $sql="SELECT UNIX_TIMESTAMP(`dt`),avg(`temp_c`) FROM `pic` WHERE 1 AND `dt`> DATE_SUB(NOW(),INTERVAL 2 DAY) group by DATE_FORMAT(`dt`,'%j.%k') ORDER BY `dt` ASC"; $result=mysql_query($sql); fwrite($fp,"# PIC Controller\n# ".date("F j, Y, g:i a")."\n#unixtime\ttemperature\n"); while ($row = mysql_fetch_assoc($result)) { if(isset($row['temp_c'])) { fwrite($fp,$row['UNIX_TIMESTAMP(`dt`)']+$TZoffset."\t".$row['temp_c']."\n"); } else { fwrite($fp,"\n"); } } fclose($fp); } </file> ==== webinfo.php ==== <file php webinfo.php> <?PHP # Jeff Brown # November 5th, 2010 # Version: 1.0 # http://photonicsguy.ca/nslu2 # Because my webhost is in another timezone... date_default_timezone_set("America/Toronto"); include('config.inc.php'); $link = @mysql_connect($MYSQL_HOST,$MYSQL_USER,$MYSQL_PASS); @mysql_select_db($MYSQL_DB); # Indoor Temperature #$sql='SELECT `temp_c` FROM `pic` WHERE 1 ORDER BY `dt` DESC LIMIT 1'; #$result=mysql_query($sql); #$row=mysql_fetch_assoc($result); #$indoortemp=$row['temp_c']; # Indoor Temperature & humidity $sql='SELECT UNIX_TIMESTAMP(`dt`),`temp_c`,`humidity` FROM `Humidity` ORDER BY `dt` DESC LIMIT 1'; $result=@mysql_query($sql); $row=@mysql_fetch_assoc($result); $ihumid=$row['humidity']; $indoortemp=$row['temp_c']; $oldest=$row['UNIX_TIMESTAMP(`dt`)']; # All Enviroment Canada Stuff $sql='SELECT * FROM `TorWeather` WHERE 1 ORDER BY `dt` DESC'; $result=@mysql_query($sql); $row=@mysql_fetch_assoc($result); $outdoortemp=$row['temperature']; $envcan=$row; $RED="#FF0000"; $BLUE="#0000FF"; if($indoortemp>0) { $icolor=$RED; } if($outdoortemp>0) { $ocolor=$RED; } else {$ocolor=$BLUE;} if($envcan['tendency']=='falling') $trend='↓'; elseif($envcan['tendency']=='rising') $trend='↑'; else $trend=''; if((is_numeric($indoortemp) AND is_numeric($outdoortemp) AND is_numeric($ihumid))) { $date=date('Y-m-d G:i',$oldest); #print "<DIV CLASS=\"rbox\">\n"; printf('Indoor Temp: <font color="%s">%0.1f°C</font><BR>',$icolor,$indoortemp); printf('Outdoor Temp: <font color="%s">%0.1f°C</font><BR>',$ocolor,$outdoortemp); printf('Indoor humidity: %0.0f%%<BR>',$ihumid); printf('Outdoor humidity: %0.0f%%<BR>',$envcan['humidity']); printf('Pressure: %s kPa %s<BR>',$envcan['pressure'],$trend); #print "<font size=1>Updated: $date</font>\n"; #print "</DIV>\n"; } else { print "Offline\n"; } ?> </file> ==== config.inc.php ==== <file php config.inc.php> <? $MYSQL_HOST='hostname'; $MYSQL_USER='username'; $MYSQL_PASS='password'; $MYSQL_DB='database'; $MYTABLE='table'; # used for Temperature.php only $INTERVAL=1; # used for Temperature.php only $YRANGE="0:70"; # used for Temperature.php only $datadir='data/'; # used for Temperature.php only #Path to gnuplot $gnuplot='/usr/bin/gnuplot'; ?> </file> archive/nslu2.txt Last modified: 2017/11/12 10:33by photonicsguy