Habe nach über einem Jahr (oder waren es sogar zwei?) meinen
IoWarrior 24 wieder hervorgeholt und eine Schaltung zur Ansteuerung von Funksteckdosen damit realisiert.
Die Beschreibung gibst bei http://www.bitplan.com/~wf/wow/TestLamp.pdf
Schaltung für Steuerung von Steckdosen
Moderator: Guido Körber
-
- Posts: 543
- Joined: Mon Dec 01, 2003 6:09 pm
Safety first
Zum Glück steht es ja schon in den ersten Zeilen der PDF - Datei:Robert Marquardt wrote:Jag einem doch keinen Schrecken ein am Samstag. :-)
Bei der Ueberschrift muss man sofort schauen ob da nicht einer Netzstrom direkt schalten will.
Goals
- Controlling 220V Power Sockets via a computer
- Safety – there should be no electrical connection between the power sockets and the computer
- Simplicity of design
Solution
- Use an off the shelf- wireless controlled Power Socket
- Use an off the shelf USB controller card
- Wire together with just two extra Ics on the test-card supplied by Code Mercenaries
Oder auf Deutsch:
Ziele
- Ansteuerung von 220 V Steckdosen mit dem Computer
- Sicherheit - es gibt keine elektrische Verbindung zwischen den Steckdosen und dem Computer
- Einfachheit des Entwurfs
Lösung
- Verwendung von handelsüblichen Funksteckdosen
- Verwendung einer handelsüblichen USB Steuerungslösung
- Zusammenbau mit nur zwei extra ICs auf dem Testaufbau den es bei Code Mercenaries gibt
Verwendete Funk-Lösung
Conrad Electronic
FS20S4UB - Batterie Unterputzsender
Funk-Schaltsteckdose FS20ST
Funkdimmer FS20DI
Mein Ziel ist damit zwei Lava-Lampen zu steuern die in grün und rot Anzeigen, ob die automatischen Testfälle unserer Software noch o.k. laufen. Der Übergang von Grün nach rot dauert mehrere Stunden, die rote Lampe geht sofort an, aber als Lava-Lampe muss die noch warm laufen. Die grüne Lampe wird langsam gedimmt. Wenn die Software nach ein paar Minuten(oder ggf. auch Stunden) wieder läuft bleibt alles im grünen Bereich - oder eben nicht - grün ist aus und die Rote Lamp läuft ... bis das Problem weg ist und wieder auf grün geschaltet wird.
Inzwischen funktioniert auch die Basis-Software auf Java Basis dazu
IOWarrior.java:
Code: Select all
/*
Copyright (C) 1999-2007 BITPlan GmbH
Pater-Delp-Str. 1
D-47877 Willich-Schiefbahn
Fon. +49 1805 BITPlan
= +49 1805 2487526
Fax. +49 2154 811 481
$Header: /usr/cvsroot/com.bitplan.testlamp/src/com/bitplan/testlamp/IOWarrior.java,v 1.1 2007/03/10 11:33:16 wf Exp $
$Id: IOWarrior.java,v 1.1 2007/03/10 11:33:16 wf Exp $
*/
/**
* test lamp program
*/
package com.bitplan.testlamp;
import com.codemercs.iow.IowKit;
/**
* simple switch mechanism for testlamp
* @author wf
*
*/
public class IOWarrior {
/** Constant for the ProductId of an IOWarrior40 */
public static final int PID_IOW40=0x1500;
/** Constant for the ProductId of an IOWarrior24 */
public static final int PID_IOW24=0x1501;
/** Constant for the ProductId of an IOWarrior56 */
public static final int PID_IOW56=0x1503;
// was open already called?
public boolean isOpen=false;
/**
* an IOWarrior handle
* @author wf
*
*/
public class Handle {
long handle;
String product,serial,revision;
/**
* initialize the handle
* @param index
* @param timeout
*/
public void init(int index, long timeout) {
handle =IowKit.getDeviceHandle(index+1);
product =Long.toHexString(IowKit.getProductId(handle));
serial =IowKit.getSerialNumber(handle);
revision=Long.toHexString(IowKit.getRevision(handle));
IowKit.setWriteTimeout(handle,timeout);
} // init
/**
* outputByte
*/
private void outputByte(int b) throws Exception{
int [] data=null;
int pid=(int)IowKit.getProductId(handle);
int datasize;
switch (pid) {
case PID_IOW24:
datasize=3;
break;
case PID_IOW40:
datasize=5;
break;
case PID_IOW56:
datasize=8;
break;
default:
datasize=0;
}
data=new int[datasize];
if (datasize>0)
data[0]=0x00; // report id
for (int i=1;i<datasize-1;i++) {
data[i]=0xFF;
}
if (datasize>0)
data[datasize-1]=b;
System.out.print("data: ");
for (int i=0;i<data.length;i++) {
System.out.print(Long.toHexString(data[i])+" ");
}
System.out.println();
long result=IowKit.write(handle,0,data);
if(result!=(long)data.length) {
throw new IOWarriorException("Error writing to device No. "+Long.toHexString(handle)+"- code "+result);
}
} // outputByte
/**
* show a Description of this handle
*/
public void showDescription() {
System.out.print ("Product = "+product);
System.out.print (" Serial = "+serial);
System.out.print (" Revision = "+revision);
System.out.println(" Handle = "+Long.toHexString(handle));
} // showDescription
} // Handle
private Handle []handles=new Handle[0];
/**
* output a given Byte
* @param b
*/
public void outputByte(int b) throws Exception {
for(int j=0;j<handles.length;j++) {
handles[j].outputByte(b);
}
} // outputByte
/**
* output the given Byte and pause for the given time
*/
public void outputByteAndPause(int b,int pause) throws Exception {
outputByte(b);
try {
Thread.sleep(pause);
}
catch(InterruptedException ie) {
}
}
/**
* presse the Button for the given channel and pause for the given time in millisecs
* @param pause
*/
public void pressButtonAndPause(int channel,int pause) throws Exception {
int lampState;
open();
lampState= 0xFF - (1 <<(channel-1));
outputByteAndPause(lampState,pause);
outputByte(0xFF);
close();
} // toggle
/**
* blink
*/
public void blink(int channel,int interval, int times) throws Exception {
open();
for (int j=0;j<times;j++) {
pressButtonAndPause(channel,interval/2);
Thread.sleep(interval/2);
} // for
close();
} // blink
/**
* list Devices of this IOWarrior
*
*/
public void listDevices() {
System.out.println("Found "+handles.length+" IOWarriors");
for(int i=0;i<handles.length;i++) {
handles[i].showDescription();
} // for
} // listDevices
/**
* open the device
* @throws Exception if no devices where found
*/
public void open() throws Exception {
if (isOpen)
return;
if(IowKit.openDevice()!=0L) {
handles=new Handle[(int)IowKit.getNumDevs()];
for(int i=0;i<handles.length;i++) {
handles[i]=new Handle();
// initialize with 1 sec writ timeout
handles[i].init(i,1000L);
} // for
//readNonBlocking();
isOpen=true;
} else {
close();
throw new IOWarriorException("No IOWarrior-Devices found");
} // if
} // open
/**
* close the device
*
*/
public void close() {
if (!isOpen)
return;
IowKit.closeDevice(0L);
isOpen=false;
}
/**
* show the Description for this device
*/
public void showDescription() throws Exception {
open();
listDevices();
close();
}
} // IOWarrior
Code: Select all
/*
Copyright (C) 1999-2007 BITPlan GmbH
Pater-Delp-Str. 1
D-47877 Willich-Schiefbahn
Fon. +49 1805 BITPlan
= +49 1805 2487526
Fax. +49 2154 811 481
$Header: /usr/cvsroot/com.bitplan.testlamp/src/com/bitplan/testlamp/IOWarrior.java,v 1.1 2007/03/10 11:33:16 wf Exp $
$Id: IOWarrior.java,v 1.1 2007/03/10 11:33:16 wf Exp $
*/
/**
* test lamp program
*/
package com.bitplan.testlamp;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import com.codemercs.iow.IowKit;
import javax.swing.AbstractButton;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.ImageIcon;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
/**
* simple lamp mechanism
* @author wf
*
*/
public class RemoteLamp {
/**
* a Button for this lamp
* @author wf
*
*/
public class LampButton extends JButton {
/**
* create a new LampButton;
* @param name
* @param iconName
*/
public LampButton(String name,String iconName, LampControler controler) {
// JButton
super(name);
ImageIcon buttonIcon = createImageIcon("resources/"+iconName);
this.setIcon(buttonIcon);
this.addActionListener(controler);
this.setActionCommand(name);
setVerticalTextPosition(AbstractButton.CENTER);
setHorizontalTextPosition(AbstractButton.LEADING); //aka LEFT, for left-to-right locales
if (name.equals("red"))
setMnemonic(KeyEvent.VK_R);
if (name.equals("green"))
setMnemonic(KeyEvent.VK_G);
setToolTipText("Click this button to switch on/off the "+name+" lamp");
}
/** Returns an ImageIcon, or null if the path was invalid. */
protected ImageIcon createImageIcon(String path) {
java.net.URL imgURL = RemoteLamp.class.getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL);
} else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
}
/**
* the controler for the lamp
* @author wf
*
*/
public class LampControler implements ActionListener,ChangeListener {
RemoteLamp lamp;
public LampControler(RemoteLamp lamp) {
this.lamp=lamp;
}
/**
* reaction on the buttons
*/
public void actionPerformed(ActionEvent e) {
try {
lamp.toggle();
} catch (Throwable th) {
Switch.failure(th,"button for "+e.getActionCommand());
}
} // actionPerformed
/**
* Listen to the dimSlider (if any)
*/
public void stateChanged(ChangeEvent e) {
try {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
int dim = (int)source.getValue();
lamp.dimTo(dim);
}
} catch (Throwable th) {
Switch.failure(th,"dim");
}
} // stateChanged
} // LampControler
public LampButton myButton;
public LampControler myControler;
public String name;
public String iconName;
public boolean isOn=false;
public boolean isDimmable=false;
public int onChannel,offChannel;
public int dimPercent;
public IOWarrior iowarrior;
public JSlider dimSlider;
/**
* create a lamp
*/
public RemoteLamp(String name, String iconName,int onChannel, int offChannel,boolean dimmable) {
this.onChannel=onChannel;
this.offChannel=offChannel;
this.name=name;
this.iconName=name;
dimPercent=-1;
isDimmable=dimmable;
myControler=new LampControler(this);
myButton =new LampButton(name,iconName,myControler);
//Create the slider.
if (dimmable) {
dimPercent=0;
dimSlider = new JSlider(JSlider.VERTICAL,0, 100,0);
dimSlider.addChangeListener(myControler);
}
}
/**
* add me to the given panel
* @param panel
*/
public void addTo(JPanel panel) {
panel.add(myButton);
if (isDimmable) {
panel.add(dimSlider);
}
}
/**
* dim the lamp to the given dimPercent
* @param dimPercent
*/
public void dimTo(int pDimPercent) throws Exception {
this.dimPercent=pDimPercent;
}
/**
* dim the lamp
* @param channel
* @param percent
* @throws Exception
*/
public void dim(int channel,int percent) throws Exception{
int factor=50;
iowarrior.open();
iowarrior.pressButtonAndPause(channel,percent*factor+420); // minimum is 400 millisecs (+5% safety limit)
iowarrior.close();
}
/**
* dim down the lamp
*/
public void dimDown(int percent) throws Exception{
dim(offChannel,percent);
} // dimUp
/**
* dim up the lamp
*/
public void dimUp(int percent) throws Exception{
dim(onChannel,percent);
} // dimUp
/**
* toggle me
* @throws Exception
*/
public void toggle() throws Exception {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
if (isOn) {
iowarrior.pressButtonAndPause(onChannel, 380); // less than 400 millisecs
if (isDimmable) {
dimDown(100);
dimUp(dimPercent);
} // isDimmable
} else {
iowarrior.pressButtonAndPause(offChannel, 400);
} // isOn
isOn=!isOn;
} catch (Throwable th) {
Switch.failure(th,"dimTo "+dimPercent);
}
}
});
}
/**
* assign an IOWarrior to this lamp
* @param iowarrior
*/
public void assignWarrior(IOWarrior iowarrior) {
this.iowarrior=iowarrior;
}
} // RemoteLamp
Code: Select all
/*
Copyright (C) 1999-2007 BITPlan GmbH
Pater-Delp-Str. 1
D-47877 Willich-Schiefbahn
Fon. +49 1805 BITPlan
= +49 1805 2487526
Fax. +49 2154 811 481
$Header: /usr/cvsroot/com.bitplan.testlamp/src/com/bitplan/testlamp/Switch.java,v 1.1 2007/03/10 11:33:16 wf Exp $
$Id: Switch.java,v 1.1 2007/03/10 11:33:16 wf Exp $
*/
/**
* test lamp program
*/
package com.bitplan.testlamp;
import com.codemercs.iow.IowKit;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JFrame;
/**
* simple switch mechanism for testlamp
* @author wf
*
*/
public class Switch extends JPanel {
/**
* constructor for the switch application
*
*/
public Switch() {
RemoteLamp redLamp =new RemoteLamp("red" ,"redbulb.jpg" ,4,3,false);
RemoteLamp greenLamp=new RemoteLamp("green","greenbulb.jpg",2,1,true);
redLamp.assignWarrior(iowarrior);
greenLamp.assignWarrior(iowarrior);
redLamp.addTo(this);
greenLamp.addTo(this);
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event-dispatching thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("Remote Lava Lamp Control");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
Switch newContentPane = new Switch();
newContentPane.setOpaque(true); //content panes must be opaque
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
protected static IOWarrior iowarrior;
/**
* display usage for the program
*
*/
public static void usage() {
System.err.println("usage: Switch on|off| blink [time]");
System.exit(1);
}
/**
* show the failure base on a Throwable
* @param th
*/
public static void failure(Throwable th) {
failure(th,null);
} // failure
/**
* show the failure based on a Throwable and a comment
* @param th
* @param comment
*/
public static void failure(Throwable th, String comment) {
System.err.println("Switch failed");
System.err.println(th.getMessage());
if (comment!=null) {
System.err.println(comment);
} else {
th.printStackTrace();
}
if (iowarrior!=null)
iowarrior.close();
System.exit(2);
}
/**
* the start of the Switch program
* @param args
*/
public static void main(String[] args) {
if (args.length<1) {
usage();
}
iowarrior=new IOWarrior();
try {
iowarrior.showDescription();
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
} catch (java.lang.UnsatisfiedLinkError ule) {
failure(ule,"You might want to copy iowkit.s0 or iowkit.dll into your LIBRARY_PATH/PATH");
} catch (com.bitplan.testlamp.IOWarriorException iwe) {
failure(iwe,"You might want to plug your IOWarrior device with your USB");
} catch (Throwable th) {
failure(th);
}
} // main
} // Switch
Wolfgang
1. vielen dank fürs teilen deiner Ergebnisse!
2. würd meine lösung ( ochne andere ICs - also mit wiederständen / Transistoren und relais vor der Fernsteuerung ) gerne mit dieser lsg modernisieren - leider habe ich ein problem mir das pdf an der interessantesten stelle also dem schaltplan anzuschaun da es da Darstellungsprobleme gibt ( sowohl mit xpdf als auch acroread). Kannst du noch mal schreiben welche ICs du da verwendet hast? Und sehe ich das ruichtig das nur die "on" switches belegt sind?
2. würd meine lösung ( ochne andere ICs - also mit wiederständen / Transistoren und relais vor der Fernsteuerung ) gerne mit dieser lsg modernisieren - leider habe ich ein problem mir das pdf an der interessantesten stelle also dem schaltplan anzuschaun da es da Darstellungsprobleme gibt ( sowohl mit xpdf als auch acroread). Kannst du noch mal schreiben welche ICs du da verwendet hast? Und sehe ich das ruichtig das nur die "on" switches belegt sind?
Erinnerung (Reklame)
Hier zur Erinnerung den Link auf meine Lösung dieser Herausforderung (Reklame): http://www.wagner-ibw.de/rfctrl.html
Die verwendeten Funksteckdosen und Schalter sind jedoch von Pollin und auch in Baumärkten zu haben.
Die verwendeten Funksteckdosen und Schalter sind jedoch von Pollin und auch in Baumärkten zu haben.