Riparazione del telecomando

Capita spesso che il telecomando della televisione, del decoder o di qualche altro apparato cada per terra… di solito senza conseguenze… Qualche volta invece il telecomando cade e smette di funzionare; non ne vuole sapere di riprendersi.

picture2

Che cosa possiamo fare? Comprare un telecomando universale da 20 euro? Ok, ma poi molto probabilmente perderemmo tutte le funzioni non standard. Perchè non provare a riapararlo da soli?

Sono due i fattori che possono alterare il corretto funzionamento di un telecomando: l’usura da utilizzo e uno shock meccanico come una caduta accidentale (o peggio il lancio volontario 🙂 ). L’usura agisce praticamente solo sulla guaina plastica dei pulsanti mentre le cadute principalmente su alcuni componenti interni (poi vedremo quali) e sulle saldature.

Ecco allora una breve check list che riporterà alla vita molti telecomandi dati per defunti:

Prima cosa fondamentale: controllare il verso delle batterie. Sembra una sciocchezza ma molto spesso un telecomando non funziona proprio perchè le batterie sono state accidentalmente messe al contrario. Dubitare di se stessi porta sempre molto lontano e soprattutto fa funzionare i telecomandi. 🙂

Numero due: batterie scariche. Per tutte le prove a seguire inseriamo delle batterie che sappiamo essere cariche. Ad esempio, prendiamo quelle di un altro telecomando che funziona regolarmente. In questo modo eliminiamo dall’equazione un’altra variabile incognita, facilitando la ricerca del guasto.

Le batterie sono cariche e al verso giusto, ma il telecomando ancora non funziona. A questo punto potrebbe essere il led emettitore guasto o dissaldato. Prendiamo una fotocamera digitale o un telefonino in modalità fotocamera e osserviamo attraverso di esso il led del telecomando. Anche se ad occhio nudo il led del telecomando appare sempre spento, in realtà emette dei veloci flash ogni volta che premiamo i pulsanti. Gli obbiettivi delle fotocamere sono abbastanza sensibili da rilevare questi flash, mostrandoci se il led effettivamente funziona oppure no. Se anche premendo i pulsanti il led rimane spento dobbiamo smontare il telecomando nelle quattro parti case plastico sotto, sopra, guaina della pulsantiera, scheda elettronica:

picture3

 

Prendiamo la scheda elettronica interna ed iniziamo ad ispezionare i componenti:

1 – Led infrarosso

picture5

Con un tester controlliamo la caduta di tensione ai capi del led, dovrebbe essere di circa 0.7 volt. Occhio al verso, il puntale rosso (positivo) sull’anodo e il puntale nero (negativo) sul catodo. In caso di dubbi provate entrambi i versi, solo in uno dei due versi dovrebbe presentarsi la caduta di 0.7 volt. Fate la prova prima direttamente sui pin del led (per testare il led stesso), poi su due altri punti della scheda elettronica direttamente connessi la led (per testare anche le saldature dei piedini del led). Se non funziona almeno il led è da cambiare o risaldare: in questo caso sostituitelo. Con un pò di fortuna il telecomando funzionerà di nuovo altrimenti se siete sfortunati si è rotto anche qualcos’altro.

Connettori delle batterie

Sono molto sensibili agli shock meccanici, con un tester controllate le saldature

Oscillatore al quarzo

picture4

L’oscillatore al quarzo è molto comune nei telecomandi moderni ed è il più sensibile dei componenti interni. E’ il componente che genera la portante a 36-46KHz  per la modulazione del segnale in uscita. Cadute accidentali possono facilmente distruggerlo anche se esteticamente risulta perfettamente integro. Sostituitelo con uno equivalente e riprovate il telecomando. Molto probabilmente il telecomando funzionerà. Essendo un componente abbastanza standard potete recuperarne uno da altri telecomandi che non utilizzate o “rotti”.

Microcontrollore

E’ molto improbabile che si guasti un microcontrollore ma potrebbe pur accadere: i piedini potrebbero essersi staccati o dissaldati. Controllateli tutti con il tester. In caso ripassateli con il saldatore applicando una leggera pressione e più stagno se necessario.

Collegare un joypad SNES al PC

Un vecchio joypad per Super Nintendo può essere riesumato e riportato in vita con qualche piccola modifica per essere usato come joypad per PC. Essenzialmente si tratta di costruire una piccola interfaccia per poterlo collegare alla porta parallela, e poi usarlo come normale joypad tramite alcuni appositi driver liberamente scaricabili su internet (più sotto trovate i link).

Dato che trovo il joypad dello SNES molto comodo da usare, ho deciso di modificarlo ed adattarlo al mio computer per usarlo con vari emulatori (dello SNES e non) e videogiochi vari.

Quello che occore:

  • saldatore a punta fine da almeno 25 Watt
  • stagno fino, meglio se con anima all’acido disossidante
  • un connettore DB25 maschio (può esser recuperato da un vecchio cavo per stampante). Assicurarsi che non sia pressofuso, altrimenti non si potrà aprire facilmente e soprattutto non si potrà inserire la nuova circuiteria all’interno
  • un connettore a scelta tra: un connettore maschio USB, un connettore maschio per alimentatori per PC, un conettore maschio per porte joystick per PC; questo connettore servirà per alimentare il joypad e bisognerà scegliere il tipo in base alle proprie esigenze: se avete una porta USB sempre libera vi conviene il primo, se non ne avete ma possedete una porta joystick potrete optare per il terzo etc… io ho deciso di adottare il connettore maschio da collegare direttamente all’alimentatore del PC, perchè bene o male sono sempre presenti in tutti i tipi di PC (tranne i portatili ovviamente). Tutte e tre le porte forniscono una tensione stabilizzata di 5volt, in grado di erogare una corrente più che sufficiente per il joypad.
  • solita roba tra forbici e nastro isolante da elettricista

Un pò di teoria sul funzionamento originale del joypad

Il connettore originale del joypad si presenta così:

images

Data l’asimmetria della forma del connettore è impossibile sbagliarsi con la numerazione.

Questa è la descrizione dei sette pin:

pintable

I pin 5 e 6 non sono usati (non esistono nemmeno i fili corrispondenti all’interno del cavo del joypad). Il pin 1 serve all’alimentazione, mentre il 2,3 e 4 servono allo scambio dei dati, infine il pin 7 provvede a dare un riferimento di massa al joypad. Tutti i segnali ricevuti e inviati da o verso il joypad sono compatibili TTL (quindi 0volt per lo 0 logico e +5volt per l’1 logico). Ogni 1/60 di secondo la console invia al joypad sul pin 3 una segnale rect di 12 microsecondi; questa pulsazione istruisce il joypad a “congelare in memoria” lo stato dei suoi pulsanti per una imminente lettura che avviene appunto 6 microsecondi dopo, quando la console invia sul pin 2 un’onda quadra al 50% di duty-cycle formata da 16 pulsazioni alla quale il joypad risponde simultaneamente inviando sul pin 4 i dati relativi allo stato dei suoi pulsanti. La risposta va considerata come 16 bit ognuno dei quali riflette lo stato (premuto/non premuto) di un pulsante (in effetti i pulsanti sono solo 12, percui le ultime 4 pulsazioni non vengono considerate).

Tutto quello che va fatto e presentare tali segnali al PC tramite la parallela, anch’essa conforme allo standard TTL, ed usare un apposito driver per interfacciarsi con il sistema DirectX di Windows, a sua volta interfaccia di comunicazione per qualsiasi gioco esistente che supporti i joypad come input.

Schema dell’interfaccia

L’intefaccia, così come era stata pensata, prevedeva l’utilizzo di cinque diodi 1N4148 da collegare alle uscite della porta parallela, i catodi dei quali erano collegati tutti al pin 1 del joypad (cavetto bianco); Questo lo schema originario:

snes_interface

Essezialmente i pin 5,6,7,8 e 9, attraverso i diodi, fornivano la potenza (tensione da 5volt e qualche mA in uscita) necessaria al joypad per poter funzionare correttamente. Ho sperimentato comunque che questo approccio non funziona sempre, ma solo su schede madri in grado di erogare sufficiente corrente dai pin della porta parallela, con le altre il joypad può non funzionare del tutto. Il problema mi si è presentato notando che cambiando computer il joypad “misteriosamente” smetteva di funzionare.

Quindi, per rendere il joypad utilizzabile un pò dappertutto ho modificato lo schema in questo modo:

snes_interface2

I diodi sono stati eliminati del tutto (il che rende l’interfaccia ancora più semplice da costruire) e l’alimentazione viene ora fornita tramite i fili A (+5 volt) e B (massa comune). Tale tensione può essere prelevata o da una porta USB libera tramite apposito connettore, o dalla porta joystick oppure direttamente da un connettore dell’alimentatore interno del PC.

Costruzione dell’interfaccia

Per realizzare l’interfaccia si può procedere tagliando via con le forbici il vecchio connettore grigio del joypad, spellare i cinque fili avendo cura di verificare che i colori corrispondano alla numerazione dei pin data nella tabella precedente (alcune versioni dello SNES hanno colori differenti); nel caso non coincidessero è bene prenderne nota e riscrivere per bene le associazioni su un foglio di carta.

Bagnare con un pò di stagno le terminazioni in rame dei fili.

Fatto ciò aprite il connettore della parallela con un cacciavite piatto (svitando oppure facendo leva se è chiuso a pressione) ed iniziate a saldare i fili del joypad sui pin corrispondenti. I cavetti 2,3 e 4 del joypad vanno saldati rispettivamente ai pin 2,3 e 10 della parallela, mentre il pin 7 va collegato ai 18 e 19.

dsub25m

Passiamo all’alimentazione:

Realizzate un cavetto di circa 30 cm che presenti ad un capo un connettore a scelta tra USB (maschio), joystick (mascho) o d’alimentazione (maschio); spellate i fili all’altro capo ed individuate i fili dei +5v e di massa.
NOTA: La numerazione dei pin è effettuata mettendo di fronte il connettore.

USB

usb_a_b_female

pin 1 +5volt
pin 4 gnd

Joystick

dsub15m

pin 1 +5volt
pin 4 gnd

Alimentatore

molex_4p

pin 1 (rosso) +5volt
pin 2 o 3 (nero) gnd

Il filo dei +5v andrà sadato al pin 1 del joypad, mentre quello di massa con il pin 7 (e quindi anche con i 18 e 19 della parallela). Fate in modo che i due cavetti (quello del joypad e quello di alimentazione passino per il buco del connettore della parallela e chiudete il tutto assicurando con qualche giro di nastro isolante.

Non rimane che scaricare i driver per poter usare il joypad:

pad_driver

Ecco alcune foto del joypad modificato

snes2

 

snes1

Forza 4 in C

Forza4, il mitico gioco a turno dove occorre allineare 4 o più pedine in una scacchiera 6×7.

In questo articolo mostro come realizzare un IA abbastamza intelligente da poter giocare decentemente contro un avversario umano.

La grafica è completamente realizzata in ASCII, quindi niente di incredibile; quello che interessa è l’algorimo dell’IA e come esso è stato implementato: il minmax.

Minmax è una funzione di valutazione in grado di minimizzare (min) la massima perdita possibile e contemporaneamente massimizzare (max) il minimo guadagno. L’algorimo è applicabile a tutti i giochi a informazione completa come forza4, scacchi, dama, tris e in generale i giochi a turno.

L’algoritmo trova la mossa migliore esplorando tutto l’albero delle possibilità da quel punto del gioco in poi; in sostanza effettua una enorme quantità di simulazioni di gioco, provando tutte le prossime possibili mosse dell’avversario, tutte le possibili contromosse successive, tutte le possibili mosse successive dell’avversario e cosi’ via fino alla fine di ogni partita “simulata”. Ovviamente il numero dei possibili sviluppi di gioco aumenta esponenzialmente al numero delle mosse provate e quindi non è possibile esplorare completamente l’albero: occorre fermarsi prima.

500px-minimax.svg

Una realizzazione concreta proverà solo un ristretto numero di mosse in avanti terminate le quali verrà valutato in una scala opportuna il vantaggio del giocatore a quel preciso stato di gioco.

Codice sorgente: forza4

/* FORZA 4 - algoritmo DFS minimax */

#define SKILL 10
#define ROW 6
#define COLUMN 7

int board[ROW*COLUMN];
long int depth,skill;
unsigned long int nodes;

void display_board(void)
{
	long int i,j;
	printf("\n");
	for(j=0;j<ROW;j++)
	{
		for(i=0;i<COLUMN;i++)
		{
			if(board[i+j*COLUMN]==1) printf("X ");
			if(board[i+j*COLUMN]==-1) printf("O ");
			if(board[i+j*COLUMN]==0) printf(". ");
		}
		printf("\n");
	}
	for(i=0;i<(COLUMN*2)-1;i++) printf("-");
	printf("\n");
	for(i=0;i<COLUMN;i++) printf("%d ",i+1);
	printf("\n");
}

int checkwin(int player,int column,int lenght)
{
	long int j,r,l,i,height;
	lenght--;
	i = column;
	j = ROW-1;
	while(board[i+j*COLUMN]!=0) j--;
	j++;
	height = j;

	r = 0;
	l = 0;
	while(((++i)<COLUMN)&&(board[i+j*COLUMN]==player)) r++;
	i = column;
	while(((--i)>=0)&&(board[i+j*COLUMN]==player)) l++;
	if ((r+l)>=lenght) return 1;
	i = column;

	r = 0;
	while(((++j)<ROW)&&(board[i+j*COLUMN]==player)) r++;
	if (r>=lenght) return 1;
	j = height;

	r = 0;
	l = 0;
	while(((++i)<COLUMN)&&((++j)<ROW)&&(board[i+j*COLUMN]==player)) r++;
	i = column;
	j = height;
	while(((--i)>=0)&&((--j)>=0)&&(board[i+j*COLUMN]==player)) l++;
	if ((r+l)>=lenght) return 1;
	i = column;
	j = height;

	r = 0;
	l = 0;
	while(((++i)<COLUMN)&&((--j)>=0)&&(board[i+j*COLUMN]==player)) r++;
	i = column;
	j = height;
	while(((--i)>=0)&&((++j)<ROW)&&(board[i+j*COLUMN]==player)) l++;
	if ((r+l)>=lenght) return 1;

	return 0;
}

int extimated_value(int player)
{
	long int i,j,value,l;

	value = 0;
	for(l=2;l<4;l++)
	{
		for(i=0;i<COLUMN;i++)
		{
			if(checkwin(player,i,l)) value = value + l;
		}
	}

	return value;
}

int goodness(int player,int depth,int column,int trigger)
{
	long int max,i,value,j;
	max = -200;
	if (checkwin(-player,column,4)) return -128;
	if (depth==0) return 0;
	for(i=0;i<COLUMN;i++)
	{
		if(board[i]==0)
		{
			j = ROW-1;
			while(board[i+j*COLUMN]!=0) j--;
			board[i+j*COLUMN] = player;
			nodes++;
			value = -goodness(-player,depth-1,i,-max)/2;
			board[i+j*COLUMN] = 0;
			if (value>max) max = value;
			if (value>trigger) return max;
		}
	}
	return max;
}

int best_move(int player)
{
	long int i,j,max,value,best,same,trigger,old,att;
	long int res[COLUMN];
	max = -100;
	best = -1;
	for(i=0;i<COLUMN;i++)
	{
		if(board[i]==0)
		{
			nodes = 0;
			j = ROW-1;
			while((board[i+j*COLUMN]!=0)&&(j>=0)) j--;
			board[i+j*COLUMN] = player;
			value = -goodness(-player,skill,i,200);
			printf("\nmove %d goodness: %d   tree size for this move: %d nodes",i+1,value,nodes);
			res[i] = value;
			board[i+j*COLUMN] = 0;
			if (value>max)
			{
				max = value;
				best = i;
			}
		}
	}
	if(best==-1)
	{
		for(i=0;i<COLUMN;i++) if(board[i]==0) return i;
	}

	return best;
}

int main(void)
{
	int move,j,i,coins;
	coins = ROW*COLUMN;
	skill = SKILL-3;

	for(i=0;i<(ROW*COLUMN);i++) board[i] = 0;
	display_board();

	while(coins!=0)
	{
		if (coins==40) skill=SKILL-2; /* quick start */
		if (coins==36) skill=SKILL-1; /* improve skill level... */
		if (coins==34) skill=SKILL;   /* ...to maximum */
		do
		{
			printf("\nchoose column [1-%d]...",COLUMN);
			scanf("%d",&move);
			if(board[move-1]!=0) printf("\ncolumn is full");
		}
		while(board[move-1]!=0);
		move--;
		j = ROW-1;
		while((board[move+j*COLUMN]!=0)&&(j>=0)) j--;
		board[move+j*COLUMN] = 1;
		coins--;
		display_board();
		if(checkwin(1,move,4))
		{
			printf("\nYou win\n");
			return 1;
		}
		move = best_move(-1);

		j = ROW-1;
		while((board[move+j*COLUMN]!=0)&&(j>=0)) j--;
		board[move+j*COLUMN] = -1;
		display_board();
		printf("\nCPU move in %d",move+1);
		coins--;
		if(checkwin(-1,move,4))
		{
			display_board();
			printf("\nCPU wins\n");
			return 1;
		}
		printf("\n");

	}
	printf("\n");
	return 1;
}

Ecco l’output del programma durante una partita:

forza4