Hallo,
ein Kollege hat sich über zwei Kräne und einen KNX Rolladenaktor einen
automatische Pferdefütterung gebaut die jeden Tag zu einer bestimmten
Zeit den Futtersack senkt und dann wieder hebt. Das Problem war das bei
kalten Temperaturen der eine Sack zu langsam gelaufen ist und somit nur
eines der beiden Pferde fressen konnte.
Dafür hab ich eine Steuerung gebaut das beiden Säcke immer die gleiche
Position haben.
1. Sensor am Motor.
Am einfachsten war es über eine Lichtschranke die Umdrehungen am
Lüfterrad zu zählen und dann einfach die Position anzufahren die nötig
ist. Leider haben die beiden Motoren so stark eingestreut, so das beide
Seite Signale gesehen haben obwohl nur ein Motor gelaufen ist. Leider
hatte ich zu dem Zeitpunkt kein Oszi, daher hab ich einfach mit ein paar
Tiefpassfiltern experimentiert, was aber nicht geholfen hat. Der zweite
Versuch war ein definiertes Signal bei jedem Impuls von der
Lichtschranke. Damit hatte ich keine Probleme mehr. Ca. 30 cm nach der
Lichtschranke sitzt der Attiny84 welcher pro Impuls von der
Lichtschranke ein 1,5 ms langen Impuls aussendet. Zum Debuggen ist eine
rot-grün LED verbaut. Die Rote LED geht an wenn die Lichtschranke
unterbrochen ist. Die grüne LED wechselt den Zustand alle 100 Impulse.
Damit das System auch bei niedrigen Temperaturen arbeitet ist ein Quarz
verbaut.
2. Steuerung
Für die Steuerung habe ich einen Atxmega64A4U verwendet da ich hier
einfach die Impulsdauer über Interrupte messen kann. Zudem nutzte ich
den DMA Modus für Debuggingausgaben über die UART. Die Kommunikation zum
PC geht über einen FT232RL. Ich habe mich bewusst gegen den USB Port am
Atxmega entschieden, da ich nicht wusste wie das die Durchlaufzeit
beeinträchtigt und USB am Atxmega hatte ich nocht nicht verwendet. Zudem
wollte ich nicht das ggf. zu hohe Pegel am Controller anliegen wenn die
Spannung weg ist aber der USB eingesteckt ist.
Die Trennung TTL 3,3V <-> TTL 5V erfolgt über zwei 74LVC1T45. Wenn eine
der beiden Seiten ohne Spannung ist wird über Pullups die RX Leitung auf
Idle-Pegel gehoben. Auf dem Ausgabeboard sind dann noch der Resettaster,
vier Taster für die Bedienung und zwei Status LEDs und zwei LEDS für
senden und empfangen. Das Ausgabeboard habe ich selber geätzt. Da ich
dafür keine Doppelseitige Platine verwenden wollte, habe ich ein paar
Brücken gesetzt und alles auf einer Seite geroutet, ggf geht aus auch
schöner.
Das "Mainboard" hat einen Traco DC/DC Wandler so das die
Betriebsspannung von 5 - 27 V betragen kann. Für Transienten ist einen
TVS Diode mit 30 V verbaut, welche noch nicht eingelötet ist. Das System
hat sechs Eingängen die von 12 bis 27 V ausgelegt sind und bei 24 V ca.
10 mA ziehen. Als Ausgangstreiber habe ich einen UDN2981A verwendet um
die Koppelrelais für die Schütze anzusteuern. Das "Mainboard" habe ich
in China ätzen lassen. Bis auf die Optokoppler, das EEPROM, der
DC/DC-Wandler und der Ausgangstreiber ist alles in SMD.
Die beiden Eingänge für die Impulse der Lichtschranken haben noch einen
kleinen Angswiderstand.
Es gibt zudem zwei One-Wire Buse welcher auch als I²C Bus genutzt werden
kann.
Für die Ausgabe der LEDs und die Laufzeitmessung der läuft der RTC mit
250 ms und erhöht einen uint8 immer im eins. Damit kann ich für die LEDs
über einfache Und-Verknüpfungen Blinkfrequenzen von 0,5 - 4 Hz erzeugen
ohne das das System blockierend ist. Die Taster und alle Eingängen sind
über einen Timer entprellt. Danke an Peter Dannegger. Ich hab das so
umgeschrieben das mit einem Timer alle drei verwendeten Ports entprellt
werden. Laut Simulator dauert die ISR 6 µs, mit dem Oszi hab ich 60 µs
über den UDN2981A gemessen.
Der Timer für der Entprellung ist gleichzeitig auch für den One-Wire Bus
zuständig.
Die Laufzeit der Motoren wird gemessen und in Abhängigkeit der
Getriebgehäusetemperatur im EEPROM gespeichert. Die Addresse hierfür ist
die 9-bit Temperatur vom DS18S20 + 110 + Offset. Für den Fall das mal
keine Signale von der Lichtschranke kommt, kann das System dann auf Zeit
fahren. Zurnot können Werte zwischen zwei Temperaturen Interpoliert
werden. Die Zeitbasis hier ist der RTC. Dadurch ensteht aber ein Fehler
von bis zu 250 ms, da nicht Sichergestellt ist das der RTC beim Start
der Motoren auf 0 steht.
Die Referenzposition für beide Seite ist der obere Endlagenschalter. Ist
das Futter nicht ganz oben fährt das System erst rauf bis zum
Endlagenschalter und dann auf die gewählte Position.
Um bei den 1,5 ms Signalen keine unnötigen 16 Bit vergleiche zu haben
prüfe ich nur auf die oberen 8 Bit ob die zwischen den beiden
Grenzwerten sind
1 | ISR(TCC0_CCA_vect)
|
2 | {
|
3 | if((TCC0.CCAH > 0x56) && (TCC0.CCAH < 0x60) )
|
4 | {
|
5 | if(down_1)
|
6 | Position_1++;
|
7 | else
|
8 | Position_1--;
|
9 | }
|
10 | CCA = TCC0.CCAL | (TCC0.CCAH<<8);
|
11 | }
|
Im Idle läuft die Hauptschleife in 22 µs durch. Damit das System bei
einer defekten Sicherung noch läuft werden die Koppelrelais für die vier
Schütze der Motoren entweder von der Steuerung versorgt oder vom
KNX-Busmodul. Fällt die Steuerung aus oder wird auf Manuell gestellt,
läuft das System wieder direkt über den KNX-Aktor.
Verhakt sich das Seil und der Sack fährt wieder rauf so stoppt das
System wenn es den oberen Endlagenschalter erreicht. Aktuell wird auch
gestoppt wenn innerhalb von 250 ms keine Impulse kommen.
Die Fahrteit nach gespeicherter Zweit muss noch programmiert
werden.Aktuell werden aber die Zeiten gespeichert.
Der Watchdog muss noch aktiviert werden, damit im Falle eines hängenden
Systems die Relais nicht dauerhaft an bleiben usw
Gruß JackFrost