Kenwood KR-A4020 Receiver distancinio valdymo atnaujinimas

23 07 2014

Aprašysiu seną, pusiau baigtą projektą. Tikslas buvo atlikti pilną turimo stiprintuvo Kenwood KR-A4020 valdymą pasinaudojant IR distancinio valdymo pultelių. Tuo metu šis stiprintuvas puikiai tiko būti naudojamu prie televizoriaus, o koks gi malonumas iki aparatūros lakstyti kai kiti įrenginiai jau turi IR distancinius pagalbininkus.  Aprašysiu kaip čia viskas gavosi. Gaila aišku kad per tą laiką praganiau PCB brėžinius kompiuteryje, bet radau spausdintų versijų, jų manau pakaks susipažinti kaip ir kas buvo daroma.

IMG_0422

Pagrindiniai tikslai projekto buvo šie:

  •  Įjungimo/išjungimo distancinis valdymas;
  • Visų esamų mygtukų distancinis valdymas;
  • Garsumo distancinis valdymas;
  • Automatinis išjungimas nesant audio signalo;

Įjungimas/Išjungimas

Originaliai stiprintuvo įjungimas vyksta per mechaninį mygtuką, kuris stiprintuvo trafui paduoda 220V. Mano sprendimas paprasčiausiai, papildomai tuos 220V perleisti per relę, kuria valdysiu aš:

onoff

 

Mygtukų valdymas

Šioje vietoje teko pasistengti. Internete radau sekančią šio stiprintuvo schemą, kurioje parodyti kaip mygtukai veikia:

CCI07232014_0003Iškarto kilo idėja per tranzistorius pajungti KR0-KR7 ir KS0-KS3 elektrodus ir valdyti kiekvieną mygtuką individualiai. Viskas su tranzistoriais būtų buvę gerai, apart to kad jų reiktu 17, o jie visi ATMEGA328P būtų valdomi individualiai. Tiek išėjimų aš neturiu, tad radau kiek kitą išeitį, kuri yra net saugesnė. Naudosiu opteronų matricą. Jų reiks taip pat 17 vienetų, bet juos valdysime per 11 mikrovaldiklio išėjimų. Pabraižius viskas atrodo taip:

CCI07232014v1

Kadangi dabar esame optiškai atskirti nuo stiprintuvo, tai nebebijome, kad kažkuri iš pusių sudegins kitą. Schemoje matosi kad mes simuliuojame mygtukų matricą. JP1 jungtis keliauja į KR0-KR7 elektrodus stiprintuve, o JP2 į KS0-KS3. Viskas atrodo kaip ir gerai apart to, kad taip nėra. Pasirodo nepakankamai išsiaiškinau stiprintuvo schemą, nes joje pasirodo įtampa mygtukuose teka ne iš KR į KS, o atvirkščiai. Tei reiškia, kad opteronų išėjimus reikia apversti, kad mano matrica veiktu tinkami:

CCI07232014_0001v2

Dabar jau viskas kaip turi būti.

Garso valdymas

Kadangi garsas valdomas analoginiu potenciometru, jo koregavimui nusprendžiau pasitelkti arba prie jo pritvirtintą DC variklį, arba tikėjausi pakeisti potenciometra į motorizuotą. Vienaip ar kitaip ši dalis taip ir buvo nebaigta, bet schemoje vietos radau DC variklio valdikliui. Ji suprojektavau dar ir taip, kad butu galima valdyti ir žingsninį variklį:

volume

Automatinis išjungimas

Ši funkcija deja irgi neišpildyta iki galo. Schema suprojektavau su audio signalo stebėjimo galimybę, tačiau programoje vis neturiu laiko įgyvendinti šio sprendimo.

audiosence

Techninis įgyvendinimas

Taigi visa schema atrodo taip:

CCI07232014_0001

PCB komponentai išdėstyti sekančiai:

CCI07232014_0002

Pagaminus ir sulitavus PCB valdymo plokštė atrodo taip:

IMG_0434

IMG_0435

 

Kaip matote nenaudojame tik audio įėjimo ir DC variklio valdymo. Taip pat truputi izoliavau 220V rėlės kontaktus, dėl viso pikto.

Laikinai plokštę patalpinau tarp pagrindinio trafo ir stiprintuvo maitinimo valdiklio izoliuodamas ją su paprasčiausiu popieriumi:

IMG_0432

Kaip taisyklė šis “laikinai“ veikia jau berods antrus metus 😀

IR imtuvas puikiai tilpo stiprintuvo panelėje virš įjungimo/išjungimo mygtuko, o karšti klijai jį laikys amžinai:

IMG_0430

 

Nuotraukoje aišku nieko nesimato, bet ne tame esmė.

Toliau mygtukų litavimas prie KR ir KS elektrodų valdymo schemoje:

IMG_0429

Litavau tiesiai prie stiprintuvo valdymo interfeiso mikroschemos, kurios kojos ir matosi nuotraukoje.

Na ir pabaigai mums reikia distancinio valdymo pultelio:

IMG_0437

Pastarasis buvo pasiskolintas nuo seno kompiuterio TV tiunerio, kuris rodo tik analogine televiziją. Tiuneris keliavo į perdirbimą, o vat pultelis tarnaus.

Programa

Viska programavau Atmega328P mikrovaldikliui su Arduino bootloaderiu. Gaila schemoje neįdėjau programavimo interfeiso, nes dabar atnaujinti programa tingiu vien todėl, kad reikia debuginti išiminėjant mikrochemą ir pan..

Štai visa paskutinė programa:


#define POWER 0x61D67887
#define TVFM 0x61D6C03F
#define SOURCE 0x61D6E01F
#define SCAN 0x61D638C7
#define MUTE 0x61D618E7
//#define FMSCANPOZ 0x61D6F807 //toks pats kaip VOLPOZ
//#define FMSCANNEG 0x61D6E817 //toks pats kaip VOLNEG
#define FMFRAQINC 0x61D620DF
#define FMFRAQDEC 0x61D630CF
#define BACKWORD 0x61D620DF
#define FORWARD 0x61D630CF
#define FUNCTION 0x61D6708F
#define RESET 0x61D6B847
#define NUM1 0x61D6807F
#define NUM2 0x61D6D02F
#define NUM3 0x61D6D827
#define NUM4 0x61D6A05F
#define NUM5 0x61D6906F
#define NUM6 0x61D6A857
#define NUM7 0x61D6609F
#define NUM8 0x61D650AF
#define NUM9 0x61D648B7
#define NUM0 0x61D640BF
#define NUMINC 0x61D608F7
#define RECAL 0x61D6C837
#define PLAY 0x61D68877
#define STOP 0x61D610EF
#define RECORD 0x61D600FF
#define MINIMAZE 0x61D6F00F
#define SNAPSHOT 0x61D658A7
#define ZOOM 0x61D69867
#define MTS 0x61D6B04F
#define CHINC 0x61D6F807
#define CHDEC 0x61D6E817
#define VOLINC 0x61D66897
#define VOLDEC 0x61D628D7
#define PRESSING 0xFFFFFFFF

#define powerRelayPin 5
#define volStepperEnablePin 4
#define but1Pin 9
#define but2Pin 10
#define but3Pin 12
#define but4Pin 13
#define but5Pin 14
#define but6Pin 15
#define but7Pin 16
#define but8Pin 17
#define butGND1Pin 8
#define butGND2Pin 7
#define butGND3Pin 6

#define audioInPin A4

#include <IRremote.h>
#include <Stepper.h>

Stepper volStepper(74, 0,1,2,3);
IRrecv irrecv(11);
decode_results current;
//decode_results before;

byte inputMode = 1;
byte newInputMode = 0;
byte radioChannel = 1;
byte newRadioChannel = 0;
byte volStep = 10;
byte power = false;
int nOn = 0; //Number of samples below threshold before turning on external power
int nOff = 0; //Number of samples above threshold before turning off external power

void setup()
{
Serial.begin(9600);
volStepper.setSpeed(60);
pinMode(volStepperEnablePin, OUTPUT);
digitalWrite(volStepperEnablePin, LOW);
pinMode(powerRelayPin, OUTPUT);
digitalWrite(powerRelayPin, LOW);
pinMode(butGND1Pin, OUTPUT);
digitalWrite(butGND1Pin, HIGH);
pinMode(butGND2Pin, OUTPUT);
digitalWrite(butGND2Pin, HIGH);
pinMode(butGND3Pin, OUTPUT);
digitalWrite(butGND3Pin, HIGH);
pinMode(but1Pin, OUTPUT);
digitalWrite(but1Pin, LOW);
pinMode(but2Pin, OUTPUT);
digitalWrite(but2Pin, LOW);
pinMode(but3Pin, OUTPUT);
digitalWrite(but3Pin, LOW);
pinMode(but4Pin, OUTPUT);
digitalWrite(but4Pin, LOW);
pinMode(but5Pin, OUTPUT);
digitalWrite(but5Pin, LOW);
pinMode(but6Pin, OUTPUT);
digitalWrite(but6Pin, LOW);
pinMode(but7Pin, OUTPUT);
digitalWrite(but7Pin, LOW);
pinMode(but8Pin, OUTPUT);
digitalWrite(but8Pin, LOW);
irrecv.enableIRIn(); // Start the receiver
}

void loop() {
while (!irrecv.decode(&current))
{
// if (power!=0)
// {
// int volume = analogRead(audioInPin);
// delay(20);
// volume = analogRead(audioInPin) - volume;
// if (abs(volume) > 5)
// {
// nOn = nOn + 1;
// if (nOn == 25) //decrease to make unit turn on faster
// {
// digitalWrite(powerRelayPin, HIGH);
// nOn = 0;
// nOff = 0;
// }
// }
// else
// {
// nOff = nOff + 1;
// if (nOff == 800) //increase to make unit stay on longer during silence
// {
// digitalWrite(powerRelayPin, LOW);
// nOff = 0;
// nOn = 0;
// }
// }
// }
}
unsigned long value = current.value;
irrecv.resume(); // Receive the next value
switch (value) {
case POWER:
digitalWrite(powerRelayPin, !digitalRead(powerRelayPin));
power = digitalRead(powerRelayPin);
break;
case VOLINC:
digitalWrite(volStepperEnablePin, HIGH);
volStepper.step(volStep);
digitalWrite(volStepperEnablePin, LOW);
break;
case VOLDEC:
digitalWrite(volStepperEnablePin, HIGH);
volStepper.step(-1 * volStep);
digitalWrite(volStepperEnablePin, LOW);
break;
case FORWARD:
newInputMode = inputMode+1;
if (newInputMode>7) newInputMode = 7;
modeChange(newInputMode);
break;
case BACKWORD:
newInputMode = inputMode-1;
if (newInputMode==0) newInputMode = 1;
modeChange(newInputMode);
break;
case SOURCE:
newInputMode = inputMode+1;
if (newInputMode>7) newInputMode = 1;
modeChange(newInputMode);
break;
case CHINC:
newRadioChannel = radioChannel + 1;
if (newRadioChannel>10) newRadioChannel = 1;
radioChannelChange(newRadioChannel);
break;
case CHDEC:
newRadioChannel = radioChannel - 1;
if (newRadioChannel==0) newRadioChannel = 10;
radioChannelChange(newRadioChannel);
break;
case NUM1:
radioChannelChange(1);
break;
case NUM2:
radioChannelChange(2);
break;
case NUM3:
radioChannelChange(3);
break;
case NUM4:
radioChannelChange(4);
break;
case NUM5:
radioChannelChange(5);
break;
case NUM6:
radioChannelChange(6);
break;
case NUM7:
radioChannelChange(7);
break;
case NUM8:
radioChannelChange(8);
break;
case NUM9:
radioChannelChange(9);
break;
case NUM0:
radioChannelChange(10);
break;
case SCAN:
pressItReal(but6Pin, butGND2Pin);
break;
case FUNCTION:
pressItReal(but8Pin, butGND2Pin);
break;
case NUMINC:
pressItReal(but3Pin, butGND2Pin);
break;
case RECAL:
pressItReal(but4Pin, butGND2Pin);
break;
case RECORD:
pressItReal(but5Pin, butGND2Pin);
break;
case RESET:
pressItReal(but7Pin, butGND2Pin);
break;
case TVFM:
if (inputMode!=1) newInputMode = 1;
else newInputMode = 5;
modeChange(newInputMode);
break;
default:
break;
}
}

void modeChange(byte index)
{
if (inputMode==2) pressItReal(but7Pin, butGND3Pin); //unpress type
inputMode = index;
switch (inputMode) {
case 1: //video
pressItReal(but4Pin, butGND3Pin);
break;
case 2: //type
pressItReal(but7Pin, butGND3Pin);
break;
case 3: //am
pressItReal(but5Pin, butGND3Pin);
break;
case 4: //fm2
pressItReal(but6Pin, butGND3Pin);
break;
case 5: //fm1
pressItReal(but3Pin, butGND3Pin);
break;
case 6: //phone
pressItReal(but1Pin, butGND3Pin);
break;
case 7: //cd
pressItReal(but2Pin, butGND3Pin);
break;
}
}

void radioChannelChange(byte index)
{
radioChannel = index;
switch (radioChannel) {
case 1:
pressItReal(but1Pin, butGND1Pin);
break;
case 2:
pressItReal(but2Pin, butGND1Pin);
break;
case 3:
pressItReal(but3Pin, butGND1Pin);
break;
case 4:
pressItReal(but4Pin, butGND1Pin);
break;
case 5:
pressItReal(but5Pin, butGND1Pin);
break;
case 6:
pressItReal(but6Pin, butGND1Pin);
break;
case 7:
pressItReal(but7Pin, butGND1Pin);
break;
case 8:
pressItReal(but8Pin, butGND1Pin);
break;
case 9:
pressItReal(but1Pin, butGND2Pin);
break;
case 10:
pressItReal(but2Pin, butGND2Pin);
break;
}
}

void pressItReal(byte butPin, byte butGNDPin)
{
digitalWrite(butPin, HIGH);
digitalWrite(butGNDPin, LOW);
delay(200);
digitalWrite(butPin, LOW);
digitalWrite(butGNDPin, HIGH);
}

Kaip matote automatinio išjungimo funkcija jau realizuota, bet jos nei testavau, nei dar kažką su ja dariau. Taip pat padarytas ir žingsninio variklio valdymas, bet deja fiziškai nieko jis nevaldo.

Rezultatas

Na o rezultatas žinoma nepilnai distancinis šio stiprintuvo valdymas. Kaip viskas veikia parodysiu video įrašuose. Pirmame kokybė gera, bet be garsų, o antrame vaizda prastas, bet su garsais:

 

Vis laukiau kokio laisvesnio laiko tikėdamasis užbaigti šį projektą, bet matydamas kad to nebebus ėmiau ir pristačiau šį savo frankenšteino tvėrinį. Gal gal kils kokių kitokių realizacijos idėjų. Manasis stiprintuvas veikia taip jau antrus metus.

 


Veiksmai

Information

Parašykite komentarą

Įveskite savo duomenis žemiau arba prisijunkite per socialinį tinklą:

WordPress.com Logo

Jūs komentuojate naudodamiesi savo WordPress.com paskyra. Atsijungti / Keisti )

Twitter picture

Jūs komentuojate naudodamiesi savo Twitter paskyra. Atsijungti / Keisti )

Facebook photo

Jūs komentuojate naudodamiesi savo Facebook paskyra. Atsijungti / Keisti )

Google+ photo

Jūs komentuojate naudodamiesi savo Google+ paskyra. Atsijungti / Keisti )

Connecting to %s




%d bloggers like this: