efinf:blc2016:bu1:projekt4:projekt

Stromsteuerung mit Arduino und Relay

Bis anhin waren die externen (Backup-)Festplatten 24h pro Tag an den Server angebunden obwohl sie nur wenige Minuten pro Tag genutzt wurden. Durch automatisches ein- und ausschalten sollte der Stromverbrauch verringert werden.

Die Stromversorgung wird von einer Arduino/Relay-Kombination übernommen, die Einbindung (mount/unmount) durch ein Python Script auf dem Server selbst.

Nach Ende der Woche was der Prototyp mehr oder weniger Funktionsfähig. Die Stromsteuerung und Kommunikation zwischen Server und Arduino bzw. Relay funktioniert einigermassen Zuverlässig, wenn auch mit einigen Sekunden Verzögerung. Die Einbindung der eingeschalteten Festplatten lässt noch zu wünschen übrig, da eine wiederholte Einbindung ohne Neustart des Servers an den temporären Ordnern der Laufwerke scheitert.

Da das Relay Netzspannung regelt wurde es in ein 3D gedrucktes Gehäuse verpackt, um Kontakt zu vermeiden.

  • Solid State Relay (z.B. https://goo.gl/aN8PzP)
  • Arduino Uno
  • 3 LEDs zum Debuggen
  • 3 220Ω Widerstände für LEDS
  • Div. Kabel

Schema mit Relay (gestrichelte Linien sind Netzspannung [230V])

code.txt

Code

Code

void setup() {
  // Serial dialect
  Serial.begin(115200);
 
  // Status LEDs
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(10, OUTPUT);
}
 
void loop() {
  // Check for input
  check_input();
}
 
void check_input() {
  if (Serial.available() > 0) {
    if (Serial.read() == '0') {
      // Device unmounted
      // Cut power
      if (cut_power() == 1) {
        // Successful
        light_pin(3);
        delay(1000);
        dark_pin(3);
      } else {
        error();
      }
    } else {
      // Wanting device
      // Give power
      if (give_power() == 1) {
        // Successful
        light_pin(6);
        delay(1000);
        dark_pin(6);
      } else {
        error();
      }      
    }
  }
  // Execution delay
  delay(100);
}
 
int cut_power() {
  // Deactivate Relay => 0V
  digitalWrite(10, LOW);
  return 1;
}
 
int give_power() {
  // Activate Relay => 5V
  digitalWrite(10, HIGH);
  return 1;
}
 
void light_pin(int pin) {
  // Turn pin on
  digitalWrite(pin, 100);
}
 
void dark_pin(int pin) {
  // Turn pin off
  digitalWrite(pin, 0);
}
 
void error() {
  // Unknown command received
  light_pin(5);
  delay(1000);
  dark_pin(5);
}
 
// 42

Verwendete Libraries

  • Pyudev - Serien Schnittstellenüberwachung (erkennt, wenn Festplatte hochgefahren ist und per USB “anklopft” https://pyudev.readthedocs.io/en/latest/
  • Python Serial - Kommunikation mit Arduino (Standart Library)
  • Python Glib - Laufzeit Library für Loops (Standart Library)

code_py.txt

Code

Code

# Imports
import serial, time, glib, os
from pyudev import Context, Monitor
from pyudev.glib import MonitorObserver
 
# Variables
dialect = 115200
timeout = 5
 
# Functions
def send_bit(bit):
	# Send bit to ardunio
	arduino = serial.Serial('/dev/ttyACM0', dialect)
	time.sleep(2)
	arduino.write(bit)
 
def mount(dev_id):
	os.system("bash mount.sh -d %s" % dev_id)
	return True
 
def unmount(dev_id):
	os.system("bash unmount.sh -d %s" % dev_id)
	return True
 
# Userinput
do = raw_input("Do you want to:\n\n(1) Power up the device\n(2) Power down the device\n\n>>> ")
 
if do == '1':
	send_bit('1')
	action = 'starting'
elif do == '2':
	send_bit('0')
	action = 'stopping'
 
print "\nCommand sent"
print "Waiting for response"
time.sleep(timeout)
 
def device_event(observer, device):
	if device.action == 'add' and action == 'starting':
		print "Device started successfully."
		print "Mounting device..."
		mount(device.get('DEVNAME'))
		exit()
	if device.action == 'remove' and action == 'stopping':
		unmount(device.get('DEVNAME'))
		print "Device shut down successfully."
		exit()
 
context = Context()
monitor = Monitor.from_netlink(context)
 
monitor.filter_by(subsystem='usb')
observer = MonitorObserver(monitor)
 
observer.connect('device-event', device_event)
monitor.start()
 
glib.MainLoop().run()

Da das Einbinden unter Windows und Linux unterschiedlich geregelt wird, wird die Einbindung in externen Scripten geregelt. Auf Linux mit mount.sh, unter Windows wäre das wohl ein Batch Script.

  • Vieles über die Verwendungszwecke von Arduinos gelernt
  • Grundlagen von Elektronik mit Relays
  • Bei Problemen Austausch mit Mitschülern

Video 3D Druck

Modell in Fusion 360

Modell des Gehäuses in Cura (3D Slicer)

Drucker bei der Arbeit

  • efinf/blc2016/bu1/projekt4/projekt.txt
  • Last modified: 2017/03/17 09:01
  • by noel_ottiger