Archive for July, 2014


To get the necesary Temperature Information i used several DS18S20 and a OneWire to USB Adapter.

As i want to use several Scripts to work with the same Temperature Data i wrote a small Deamon to get the Temperature Data via digitemp and save it in “sensor” files under /tmp/sensorN. OneWire Fs only gave wrong Temperature Data (85°C) and the nodejs script got some serious problems with digitemp.

NOTE: I created two UDEV rules to get a “static” path for the two serial devices(Outlet and 1Wire Adapter)

cat /etc/udev/rules.d/44-ttyusb.rules
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", ATTRS{serial}=="A6XDT7AO", SYMLINK+="steckdose", ACTION=="add"
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="ea90", ATTRS{serial}=="10TK4WX6", SYMLINK+="onewire", ACTION=="add"

At first you need to initialize your digitemp config file:

digitemp -i -s /dev/onewire -c /etc/digitemp.conf 

The next step is to create the Daemon under /usr/local/bin/onewire/onewire.pl:

#!/usr/bin/perl

use strict;
use warnings;

use Proc::Daemon;
use Proc::PID::File;

MAIN:
{
	# Daemonize
	Proc::Daemon::Init;

	# If already running, then exit
	if (Proc::PID::File->running()) {
		exit(0);
	}

	my $continue = 1;
	$SIG{TERM} = sub { $continue = 0 };
	
	my $temperature;
	my $c = 0;
	my $sensor_count = 0;
	
	# Get Sensor #
	open DIGITEMPCONF, "<", '/etc/digitemp.conf' || die "Can't open /etc/digitemp.conf: $!";
	while() {
	        if($_ =~ m/SENSORS/) {
	                my @tmp = split(' ',$_);
	                $sensor_count = $tmp[1];
	        }
	}
	
	# filling sensor files arra<
	my @sensorfiles;
	
	for(my $i = 0; $i ", $sensorfile || die "Can't open $sensorfile: $!";
			$temperature = 85;
			while ($temperature == 	85) {
				$temperature = `/usr/bin/digitemp -c /etc/digitemp.conf -t$c -q -o"%.2C" -r1000`;
			}
			print $temp_sensorfile $temperature;
			print $temperature;
			close $temp_sensorfile;
			$c++;
		}
		$c = 0;
		sleep(15);
	}
	close DIGITEMPCONF;
}

And a start stop script under /etc/init.d/onewire (install it with update-rc.d onewire defaults)

#!/bin/sh
### BEGIN INIT INFO
# Provides:          onewire
# Required-Start:    
# Required-Stop:
# Should-Start:
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6 
# Short-Description: Starts the onewire "daemon" to provide onewire sensor datat under /tmp/sensorN
# Description: Starts the onewire "daemon" to provide onewire sensor datat under /tmp/sensorN       
### END INIT INFO

PATH=/sbin:/usr/sbin:/bin:/usr/bin
. /lib/init/vars.sh

do_start () {
	/usr/local/bin/onewire/onewire.pl
}

do_status () {
	if [ -f /var/run/onewire.pl.pid ] ; then
		echo "onewire is running";
		return 0
	else
		echo "onewire is not running";
		return 4
	fi
}
do_stop () {
	killall onewire.pl
}

case "$1" in
  start|"")
	do_start
	;;
  restart|reload|force-reload)
	do_stop
	rm /tmp/sensor*
	do_start
	;;
  stop)
	do_stop
	;;
  status)
	do_status
	exit $?
	;;
  *)
	echo "Usage: onewire [start|stop|status]" >&2
	exit 3
	;;
esac

:

After a lovely /etc/init.d/onewire restart you go the sensor data for each sensor under /tmp/sensorN
for example:

cat /tmp/sensor0
24.19

The sensor data will be updated every 15 seconds and the N in the sensor file is the same number you can find in the digitemp config (/etc/digitemp.conf).

Advertisements

Since my actual Terrarium Controller got serious problems with the usb power strip, I bought a raspberry pi and a Ninja Pi Crust to update the old System.

The old System contains of the following Elements:
– 1Wire Temperature Sensor
– USB Power Strip (sispm)
– WebInterface
– Many Shell Scripts to switch outlets on/off
– Big Crontab…

The new System should consist of the following Elements:
– 1Wire Temperature Senso
– Power Strip based on some very cheap replaceable components like arduino, releay modules
– reworked Terrarium Conroll Scripts based on Perl without big crontab…
– Fancy webinterface with graphs and buttons
– Maybe controlling some more items 😉

As power strip I used a 4 Port relay in combination with some “Aufputz” Power sockets and a Arduino Pro mini.

outlet_1
I connected the four relay Ports to the Arduino, disabled the Auto reset and uploaded the following Code:

 
//#define DEBUG

int CH1 = 9;
int CH2 = 12; 
int CH3 = 11; 
int CH4 = 10; 

String Input;
int ch1Value = 0;
int ch2Value = 0;
int ch3Value = 0;
int ch4Value = 0;
int ChSelected = 0;
int ChValue = 0;

void setup()
{
  pinMode(CH1, OUTPUT);      // sets the digital pin as output
  digitalWrite(CH1, HIGH); 
  pinMode(CH2, OUTPUT);      // sets the digital pin as output
  digitalWrite(CH2, HIGH);
  pinMode(CH3, OUTPUT);      // sets the digital pin as output
  digitalWrite(CH3, HIGH);  
  pinMode(CH4, OUTPUT);      // sets the digital pin as output
  digitalWrite(CH4, HIGH); 
        
       
     
    
  Serial.begin(9600);
  #ifdef DEBUG
    Serial.println("DEBUG!!!");
    Serial.println("Started");
  #endif
}

void loop()
{
  while (Serial.available()) 
  {
    delay(3);  //delay to allow buffer to fill 
    if (Serial.available() >0) 
    {
      char c = Serial.read();  //gets one byte from serial buffer
      if(c  != ';')
      {
        Input += c; //makes the string readString
      }
      else
      {
        ParseInput();
      }

    } 
  }

}

void ParseInput()
{
  //10;
  //Define single Channels
  if (Input.length() == 2) 
  {
#ifdef DEBUG
    Serial.print("Got: ");
    Serial.println(Input); 
#endif
ChSelected = Input.substring(0,1).toInt();
ChValue = Input.substring(1,2).toInt();
#ifdef DEBUG
    Serial.print("Selected Channel: ");
    Serial.println(ChSelected); 
    Serial.print("Value: ");
    Serial.println(ChValue); 
#endif
// Set:1,1
Serial.print("Set:");
    switch (ChSelected) 
    {
      case 1:
        #ifdef DEBUG
        Serial.print("Case 1 ");
        #endif      
        digitalWrite(CH1, !ChValue);
        ch1Value = ChValue;
        Serial.print("1,");
        Serial.print(ChValue);
      break;
      case 2:
        #ifdef DEBUG
        Serial.print("Case 2 ");
        #endif 
        digitalWrite(CH2, !ChValue);
        ch2Value = ChValue;
        Serial.print("2,");
        Serial.print(ChValue);
      break;
      case 3:
        #ifdef DEBUG
        Serial.print("Case 3 ");
        #endif 
        digitalWrite(CH3, !ChValue);
        ch3Value = ChValue;
        Serial.print("3,");
        Serial.print(ChValue);   
      break;
      case 4:
        #ifdef DEBUG
        Serial.print("Case 4 ");
        #endif 
        digitalWrite(CH4, !ChValue);
        ch4Value = ChValue;
        Serial.print("4,");
        Serial.print(ChValue);  
      break;
    }
    Serial.println(";");
     Input="";
  } 
  //1; 
  //Status for Channel
  else if (Input.length() == 1)
  {
    ChSelected=Input.toInt();
    #ifdef DEBUG
    Serial.print("Got status request for: ");
    Serial.print(ChSelected); 
    #endif
    //Status:1,1
    Serial.print("Status:");
    switch (ChSelected) 
    {
      case 1:
        #ifdef DEBUG
        Serial.print("Case 1 ");
        #endif
        Serial.print("1,");      
        Serial.print(!digitalRead(CH1));
      break;
      case 2:
        #ifdef DEBUG
        Serial.print("Case 2 ");
        #endif
        Serial.print("2,");    
        Serial.print(!digitalRead(CH2));
      break;
      case 3:
        #ifdef DEBUG
        Serial.print("Case 3 ");
        #endif
        Serial.print("3,");    
        Serial.print(!digitalRead(CH3));
      break;
      case 4:
        #ifdef DEBUG
        Serial.print("Case 4 ");
        #endif 
        Serial.print("4,");   
        Serial.print(!digitalRead(CH4));
      break;
    }
    Serial.println(";");
    Input="";
    
  }
  //10,20,30,41;
  //Define all Channels
  else if (Input.length() == 11)
  {
    #ifdef DEBUG
    Serial.print("Got; ");
    Serial.println(Input);
    #endif
    ch1Value=Input.substring(1,2).toInt();
    ch2Value=Input.substring(4,5).toInt();
    ch3Value=Input.substring(7,8).toInt();
    ch4Value=Input.substring(10,11).toInt();

    #ifdef DEBUG
    Serial.print("ch1Value: ");
    Serial.println(ch1Value);
    Serial.print("ch2Value: ");
    Serial.println(ch2Value);
    Serial.print("ch3Value: ");
    Serial.println(ch3Value);
    Serial.print("ch4Value: ");
    Serial.println(ch4Value);
    #endif    
    digitalWrite(CH1, !ch1Value); 
    digitalWrite(CH2, !ch2Value);   
    digitalWrite(CH3, !ch3Value);   
    digitalWrite(CH4, !ch4Value); 
    Input="";
  }
 Input="";
}

The next step was to connect a 5V FTDI Adapter to the Arduino and place everything in the “Aufputz” case.
Now you have a usb controlled outlet 😉

Switch outlet on/off:
Command:$Outlet,$State(0,1);
Returns: Set:$Outlet,$Status
Example:

 
1,0;
Set:1,0
1,1;
Set:1,1

Get Status of Outlet:
Command:$Outlet
Returns: Status:$Outlet,$Status
Example:

 
1;
Status:1,1

Hi,
if you receive the following Messages while restarting the NinjaBlock Service (stopninja && startninja)

/sys/devices/virtual/gpio/gpio23/value: No such file or directory

or

[System] Sun Jan  5 01:17:07 EST 2014 Flashing Arduino...Pass 1 Failed!
avrdude: stk500_getsync(): not in sync: resp=0xe0

or

`/sys/devices/virtual/gpio/gpio23/*': No such file or directory

Maybe your GPIO Pins are not exported any more…
The following command resolves the issues for me:

echo 23 > /sys/class/gpio/export