Hi,
da ich mich recht lange nicht gemeldet habe, denke ich es ist Zeit für ein kleines Update.
Dia Platine wurde nochmal penibelst auf Fehler überprüft und doch tatsächlich am 25. November von meiner Liebsten geätzt, verzinnt und gebohrt. Sie hat davon sogar zwei kleine Videos gemacht, da ich nicht dabei sein konnte.
Platine ätzen:
https://youtu.be/o0Zd5CTKPlQ
Platine verzinnen:
https://youtu.be/x4NgNGTpUOo
Platine nach dem Bohren:
Wie ihr seht wurde aus meiner VolSource ein VolSouce. Ich denke ich werde da ein bisschen mit Silberleitlack nacharbeiten und ein Vol
Sauce draus machen. Dann machts wenigstens wieder Sinn :p
Daraufhin wurde die Platine bestückt. Da fiel mir auch gleich der 2. Fehler auf. Habe ausversehen vor eine Schraubklemme einen Transistor gehangen. Aber das beeinträchtigt die Funktion nicht sonderlich. Trotzdem ärgerlich :mad:
Von oben:
von unten (ich bin ein Künstler, speziell bei dem LS Relais

):
Die Pulldown Widerstände für die FETs und die Widerstände zum Entladen habe ich auch mit dem normalen Lötkolben gelötet. Etwas fummelig, aber machbar. Hier ein Bild von den Pulldown-Widerständen der FETs:
Habe die Platine dann natürlich auch gleich ausgiebig getestet. Zum Glück funktioniert alles so wie ich mir das gedacht habe. Nix am Brummen, alles gut. Lediglich das Motorpoti hat sich für meinen Geschmack ein bisschen zu langsam gedreht. Dieser wird über eine Doppel-H Brücke gesteuert, da der µC Port nur 20mA kann und der Motor 150mA zieht und da dies die einfachste Lösung ist, den Motor vorwärts und rückwärts drehen zu lassen.
Beim blick ins Datenblatt fiel mir dann ein, dass prinzipbedingt bei dieser H-brücke 1,7V (weiß ich nicht mehr 100%) durch Dioden in den FETs, mit denen die Brücke arbeitet, abfallen. jedoch hatte ich gerademal knapp 2,5V statt 3,3V, die ja dann eigentlich anliegen dürften. Mein Onkel hat dann mal sein Oszilloskop mitgebracht und wir haben direkt am Mikrocontroller ausgang gemessen und dadurch bemerkt, dass der Fehler im Code liegt:
Der Code wurde entsprechend angepasst und schon hatte ich meine 3,3V wieder zur Verfügung für den Motor. Dreht auf jeden Fall schnell genug laut und leise.
Die Elektronik funktioniert also soweit. So kam ich nun zu dem letzten Schritt. Das Gehäuse. Das Gehäuse wurde komplett in CAD entworfen, um vorher sagen zu können, wie viel Platz in etwa gebraucht wird.
Dafür musste ich nun erstmal die beiden Kühlkörper bestellen, die die Seiten ergeben sollen. Zunächst wurden die Kühlkörper bei Schuro in Kassel bestellt, da sie dort wirklich günstig angeboten wurden. Da ich jedoch nach über einem Monat nach mehreren vergeblichen Anrufen und Emails keinerlei Reaktion wahrnehmen konnte, wurde storniert und wo anders bestellt. Schade eigentlich, da ich auch jeden Tag in Kassel bin und bei erfolgreicher Kontaktaufnahme gerne mal da vorbei geschaut hätte. Pech gehabt. Bei der anderen Firma gings dann zum Glück recht schnell und ich hatte die schwarzen brocken auf dem Tisch liegen:
Die Frontplatte hat mir ein Bekannter zugeschnitten. Im Anschluss wurde von mir gebohrt und ich hab die Satiniermaschine geschwungen. Ich hätte gerne 10er Material gehabt, es wurde im Endeffekt "nur" 8er Material. Gefällt mir aber trotzdem ganz gut.
Auf dem ersten Bild siehts etwas komisch aus. Da war glaube noch ein bisschen staub drauf. Hatte es etwas abgewischt. Auf dem zweiten sieht man, dass es doch recht gleichmäßig ist:
Der Deckel wurde auch gleich auf der Tafelschere geschnitten, gebohrt, satiniert und im Anschluss mit dem groben Polierfließaufsatz poliert. Leider ist das Bild etwas unscharf. Ihr werdet denke sofort das versetzte Lüftunksloch links sehen. Ich denke das gehört beim DIY auch mal dazu:
Hier sieht man nochmal schön den Schliff:
So siehts dann zusammengebaut aus, mir gefällts:
Dann wurde auch gleich begonenn, die ganzen Abstandshalter zu setzen und im Allgemeinen die Aufteilung zu machen und die Module einzubauen (fehlen noch ein paar, mir gingen die Abstandshalter aus):
Daten zum Material:
Frontplatte 8mm, AlMg3
Deckel 3mm, AlMg3
Rückseite 3mm, AlMg3
Boden: 2mm verzinkter Stahl
AlMg3 wurde extra so gewählt, da die Teile alle eloxiert werden sollen und das mit der Legierung gut funktioniert. Wegen Farben lasst euch überraschen. Habe die Teile am Montag abgegeben. 1 Woche solls dauern. ich bin gespannt, wie das ergebnis wird. Die Frontplatte hat überigens noch ein paar Löcher mehr bekommen für Lichtsensor, IR-Sensor, Status LED und Lautstärkepoti. Mir fehlen jetzt wirklich nur noch Kleinigkeiten. Die Verkabelung wird auf jeden Fall nochmal ein Spaß.
Software wurde auch etwas angepasst:
-Spannungsproblem gelöst
-Adaptive Helligkeit der Status LED, sodass diese dunkler wird, wenn es im Zimmer dunkel ist
Für die Interessierten hier der aktuelle Code:
Code:
#include <Arduino.h>
/*****************************
*Relaisboard mit Apple Remote*
*****************************/
//Oben => Lauter
//Unten => Leiser
//Links => Quelle vor
//Rechts => Quelle zurück
//Mitte => Verstärker ein/aus
//Play/Pause => Mute ein/aus
byte Ch1 = 2; //Relais fuer Ch1 auf Pin 2
byte Ch2 = 3; //Relais fuer Ch2 auf Pin 3
byte Ch3 = 4; //Relais fuer Ch3 auf Pin 4
byte Ch4 = 5; //Relais fuer Ch4 auf Pin 5
byte Ch5 = 6; //Relais fuer Ch5 auf Pin 6
byte Ch6 = 7; //Relais fuer Ch6 auf Pin 7
//byte LineOut = 8; //Relais fuer Lineoutkanal auf Pin 8
byte LsRelais = 8; //Relais fuer Lautsprecher auf Pin 9
byte PowerLED = 9; //Betriebs-LED
byte IRpin = 10; //Infrarotsignal auf Pin 10
byte VolUp = 11; //Vol+ auf Pin 11
byte VolDown = 12; //Vol- auf Pin 12
byte PowerRelais = 13; //Traforelais auf Pin 13
int analogLight = 3; //Lichtsensor (LDR) auf Analogeingang 3
//Schaltung [5V]--(LDR)--[SIGNAL]--(20k)--[GND]
// I
// [A3]
/********************/
/****EINSTELLUNGEN***/
/********************/
int SwichDelay = 100; //Umschaltzeit bei Quellenwahl (500ms =>bei 0ms öffnet Lautsprecherrelais; bei 250ms Quellenwechsel; bei 500ms schließt Lautsprecherrelais)
int WarmUp = 1000; //Zeit in [ms] bis Lautsprecherrelais nach Einschalten schließt
int CoolDown = 3000; //Zeit in [ms] bis Traforelais nach Ausschalten öffnet
byte HoldOnCount = 0; //Relative Zeit, die die Taste Mitte gedrückt werden muss, um den Verstärker Einzuschalten
byte HoldOffCount = 2; //Relative Zeit, die die Taste Mitte gedrückt werden muss, um den Verstärker Auszuschalten
byte StartCh = Ch1; //Pin des Startkanals nach Stromzufuhr <=> ChNr ANPASSEN!
int ChNr = 0; //Ch1<=>0 Ch2<=>1 Ch3<=>2 Ch4<=>3 Ch5<=>4 Ch6<=>5
int PowerStat = -1; // 1 -> Verstärker an, nachdem Stecker eingesteckt wurde =>Power=1 setzen
// -1 -> Verstärker bleibt aus, nachdem Stecker eingesteckt wurde =>Power=0 setzen
#include <IRremote.h> //Einbinden der IRremote Bibliothek
char ChStat [6] {Ch1, Ch2, Ch3, Ch4, Ch5, Ch6};
long VolUpTime = 0;
long VolDownTime = 0;
long VolRepTime = 0;
byte VolUpFinish1 = 0;
byte VolUpFinish2 = 0;
byte VolDownFinish1 = 0;
byte VolDownFinish2 = 0;
int VolStat = 0;
long SwichTimeUp = 0;
long SwichTimeDown = 0;
boolean mute = 0;
int WarmUpStat = 0;
long LsSafeTime = 0;
int BeforeSwich = 0;
int SwichStat = 0;
boolean Power = 1;
long PowerOnTime = 0;
long PowerOffTime = 0;
int PowerOnCount = 0;
int PowerOffCount = 0;
float LightWriteValue = 0;
int SinLightWriteValue = 0;
float LightSinAngle = 0;
IRrecv irrecv(IRpin); //IRpin ist IR Empfänger
decode_results results;
void setup() {
Serial.begin(9600);
pinMode (Ch1, OUTPUT);
pinMode (Ch2, OUTPUT);
pinMode (Ch3, OUTPUT);
pinMode (Ch4, OUTPUT);
pinMode (Ch5, OUTPUT);
pinMode (Ch6, OUTPUT);
//pinMode (LineOut, OUTPUT);
pinMode (LsRelais, OUTPUT);
pinMode (VolUp, OUTPUT);
pinMode (VolDown, OUTPUT);
pinMode (PowerRelais, OUTPUT);
pinMode (PowerLED, OUTPUT);
if(PowerStat == -1)
{
Power = 0;
}
else
{
Power = 1;
}
irrecv.enableIRIn(); //IR Empfänger starten
}
void GetBrightness(byte MinBrightness)
{
LightWriteValue = (analogRead(analogLight)/8)-5; //Sensorwert einlesen
if(LightWriteValue > 255) //Setzt LED Helligkeit auf 255, wenn errechneter Wert größer 255
{
LightWriteValue = 255;
}
if(LightWriteValue <= MinBrightness) //Setzt LED Helligkeit auf MinBrightness, wenn errechneter Wert kleinergleich MinBrightness
{
LightWriteValue = MinBrightness;
}
return;
}
void SinBlink (int Speed)
{
LightSinAngle = (float) millis()/Speed; //Fortlaufender Wert, "2500" legt Speed fest
SinLightWriteValue = LightWriteValue/2 + LightWriteValue/2 * sin( LightSinAngle * 2.0 * PI );//Erzeugt Wert mit Sinus Verlauf zwischen null und
//eingegebenem Wert
analogWrite(PowerLED, SinLightWriteValue);
return;
}
void loop() {
/***********
*IR Empfang*
***********/
if (irrecv.decode(&results))
{
/************
*Quellenwahl*
************/
if(Power == 1) //Wird nur ausgeführt, wenn Gerät eingeschaltet
{
if (results.value == 2011291771) //Wenn IRCode RECHTS
{
LsSafeTime = millis();
SwichTimeUp = millis();
SwichStat = 1;
ChNr++;
if (ChNr == 6) //Zurücksetzen des Zählers am Ende
{
ChNr = 0;
}
VolStat = 0;
irrecv.enableIRIn();
}
else if (results.value == 2011238523) //Wenn IRCode LINKS
{
LsSafeTime = millis();
SwichTimeDown = millis ();
SwichStat = -1;
ChNr--;
if (ChNr == -1) //Zurücksetzen des Zählers am Ende
{
ChNr = 5;
}
VolStat = 0;
irrecv.enableIRIn();
}
}
/*****************
*Lautstärke hoch*
*****************/
if (results.value == 2011287675) //Wenn IRCode OBEN
{
VolStat = 1;
VolUpFinish1 = 0;
VolUpTime = millis();
irrecv.enableIRIn();
}
if (results.value == 4294967295 && VolStat == 1 && millis() - VolUpTime <= 15000)//Wenn IRCode Wiederholungscode nach Oben gedrückt wurde
{
VolRepTime = millis();
irrecv.enableIRIn();
}
/*******************
*Lautstaerke runter*
*******************/
else if (results.value == 2011279483) //Wenn IRCode UNTEN
{
VolStat = -1;
VolDownFinish1 = 0;
VolDownTime = millis();
irrecv.enableIRIn();
}
else if (results.value == 4294967295 && VolStat == -1 && millis() - VolDownTime <= 15000)//Wenn IRCode Wiederholungscode nachdem Unten gedrückt wurde
{
VolRepTime = millis();
irrecv.enableIRIn();
}
/*************
*Mutefunktion*
*************/
else if (results.value == 2011265659 && WarmUpStat == 1) //Wenn IRCode PLAY/PAUSE
{
if (mute == false)
{
digitalWrite(LsRelais, LOW);
mute = 1;
}
else if (mute == true)
{
digitalWrite(LsRelais, HIGH);
mute = 0;
}
irrecv.enableIRIn(); //IR Empfänger starten
VolStat = 0;
}
else if (results.value == 2011250811) //Wenn IRCode MENÜ
{
irrecv.enableIRIn(); //IR Empfänger starten
VolStat = 0;
}
else if (results.value == 2011282043) //Wenn IRCode MITTE
{
if (Power == 0) //Wenn AUS
{
PowerStat = 1;
PowerOnCount = 0;
}
if (Power == 1) //Wenn AN
{
PowerStat = -1;
PowerOffCount = 0;
}
irrecv.enableIRIn(); //IR Empfänger starten
VolStat = 0;
}
if (results.value == 4294967295 && PowerStat == 1) //Wenn IRCode Wiederholungscode nachdem MitteAn gedrückt wurde
{
PowerOnCount++;
}
if (results.value == 4294967295 && PowerStat == -1) //Wenn IRCode Wiederholungscode nachdem MitteAus gedrückt wurde
{
PowerOffCount++;
}
irrecv.enableIRIn();
irrecv.resume();
}
/******
*Timen*
******/
/*Ausschalten*/
if (PowerOffCount >= HoldOffCount && PowerStat == -1)
{
PowerOffTime = millis();
digitalWrite(LsRelais, LOW);
WarmUpStat = 0;
PowerStat = 0;
Power = 0;
PowerOffCount = 0;
}
if (PowerOffTime != 0 && PowerOffTime <= millis() - CoolDown && Power == 0)
{
digitalWrite(PowerRelais, LOW);
digitalWrite(ChStat [ChNr], LOW);
PowerStat == 0;
PowerOffTime = 0;
}
/*Einschalten*/
if (PowerOnCount >= HoldOnCount && PowerStat == 1)
{
PowerOnTime = millis();
digitalWrite(ChStat [ChNr], HIGH);
digitalWrite(PowerRelais, HIGH);
PowerStat = 0;
Power = 1;
PowerOnCount = 0;
}
if (millis()-PowerOnTime >= WarmUp && WarmUpStat == 0 && Power == 1)
{
digitalWrite (LsRelais, HIGH);
WarmUpStat = 1;
}
/*Lautsprecherschutz und Quellenwahl*/
if (LsSafeTime >= millis() - SwichDelay &&Power ==1) //Wenn LsSafeTime weniger als 300ms zurück liegt
{
analogWrite(LsRelais, LOW);
}
else if (LsSafeTime <= millis() - SwichDelay && mute == 0 && WarmUpStat == 1 &&Power ==1) //Wenn LsSafeTime mehr als 300ms zurückliegt UND kein Mute aktiviert ist UND Warmup absolviert ist
{
digitalWrite(LsRelais, HIGH);
}
if (SwichTimeUp <= millis() - SwichDelay/2 && SwichStat == 1)
{
for(byte i = 0; i<6; i++)
{
digitalWrite(ChStat [i], LOW);
}
digitalWrite(ChStat [ChNr], HIGH);
SwichStat = 0;
}
if (SwichTimeDown <= millis() - SwichDelay/2 && SwichStat == -1)
{
for(byte i = 0; i<6; i++)
{
digitalWrite(ChStat [i], LOW);
}
digitalWrite(ChStat [ChNr], HIGH);
SwichStat = 0;
}
/*VolUp*/
if (VolUpTime >= millis() - 300 && VolStat == 1) //Wenn VolUpTime weniger als 300ms zurück liegt
{
digitalWrite(VolUp, HIGH);
VolUpFinish1 = 0;
}
if (VolUpTime <= millis() - 300 && VolUpFinish1 == 0) //Wenn VolUpTime mehr als 300ms zurückliegt
{
digitalWrite(VolUp, LOW);
VolUpFinish1 = 1;
}
if (VolRepTime >= millis() - 300 && VolStat == 1) //Wenn VolRepTime weniger als 300ms zurück liegt und VolStat = 1
{
digitalWrite(VolUp, HIGH);
VolUpFinish2 = 0;
}
if (VolRepTime <= millis() - 300 && VolStat == 1 && VolUpFinish2 == 0) //Wenn VolRepTime mehr als 300ms zurück liegt und VolStat = 1
{
digitalWrite(VolUp, LOW);
VolUpFinish2 = 1;
}
/*VolDown*/
if (VolDownTime >= millis() - 300 && VolStat == -1) //Wenn VolDownTime weniger als 300ms zurück liegt
{
digitalWrite(VolDown, HIGH);
VolUpFinish1 = 0;
}
if (VolDownTime <= millis() - 300 && VolDownFinish1 == 0) //Wenn VolDownTime mehr als 300ms zurückliegt
{
digitalWrite(VolDown, LOW);
VolDownFinish1 = 1;
}
if (VolRepTime >= millis() - 300 && VolStat == -1) //Wenn VolRepTime weniger als 300ms zurück liegt und VolStat = -1
{
digitalWrite(VolDown, HIGH);
VolDownFinish2 = 0;
}
if (VolRepTime <= millis() - 300 && VolStat == -1 && VolDownFinish2 == 0) //Wenn VolRepTime mehr als 300ms zurück liegt und VolStat = -1
{
digitalWrite(VolDown, LOW);
VolDownFinish2 = 1;
}
/***********************************
*Betriebs LED, Helligkeitssteuerung*
***********************************/
if(Power == 1 && mute == 0 && WarmUpStat == 0) { //In der Warmlaufphase
GetBrightness(10);
SinBlink(100);
}
if(Power == 1 && mute == 0 && WarmUpStat == 1) { //Wenn eingeschaltet und Mute inaktiv
GetBrightness(1);
analogWrite(PowerLED, LightWriteValue);
}
else if (Power == 0) { //Wenn ausgeschaltet
digitalWrite(PowerLED, LOW);
}
else if (Power == 1 && mute == 1) { //Wenn eingeschaltet und Mute aktiv
GetBrightness(10);
SinBlink(2500);
}
}
@Kalle
Danke fürs Lob und deine Anregungen.
Für die Lautsprecherschutzschaltung habe ich auf dem Board Lötaugen vorgesehen. Ich müsste mich nochmal damit befassen, wie ich die Erkennung am besten realisiere ohne fertiges Modul. Der Arduino soll das ganze dann ohne extra Schutz-Module für mich erkennen und entsprechend reagieren, indem er die LS_Relais öffnet oder gleich die Spannung von den Trafos nimmt. Vielleicht kann mir ja jemand erklären, auf was genau die Schutzschaltung dann reagieren sollte. Ich denke jedoch, dass das mit ein paar Standard Bauteilen und angepasster Software funktionieren sollte.
Habe auf der Rückplatte zwei Cinch-Ausgänge und zwei Cinch-Eingänge vorgesehen. So kann ich bei Bedarf imemrnoch was zwischen Quellenwahl und Verstärker schleifen. Platz für eine zweite kleine Stufe wäre auch noch vorhanden denke ich. Aber ich denke bis jetzt noch nicht an sowas.
Beste Grüße
Simon