GuifiReset

De Guifi.net - Wiki Hispano

Las máquinas no son perfectas y muchas veces alcanzan estados que el programador no previno o que por otros motivos no pudo arreglar. En muchos de esos casos, la mejor solución es "apagar y encender".

Aquí se describe una posible solución casera para reiniciar nodos de forma remota y que puede crear cualquiera con ganas y unos conocimientos básicos de electrónica. En este prototipo, el relé en lugar de alimentarse a 12VDc funciona directamente a 5VDc, por tanto, cogiendo únicamente 5V del PC podemos alimentar todo el sistema sin ninguna fuente de alimentación extra.

El autor es Josep Figueras y la mayor parte del contenido se ha extraído de este mensaje en la lista de desarrollo.

¡Si haces alguna mejora sobre este prototipo, acuérdate de compartirla también con nosotros!

Componentes

Lista de componentes que podrás encontrar en cualquier tienda de electrónica:

  • 1x MAX232
  • 1x PIC16F877A
  • 1x BC547C
  • 1x Relé
  • 2x Resistencia 1K
  • 1x Resistencia 10K
  • 1x Resistencia 3k3
  • 2x Condensador 47pF
  • 4x Condensador 4µF
  • 1x Oscilador 20MHz
  • 1x Diodo LED

Precio aproximado: --€

Esquemáticos

Haz click en las imágenes para verlas más grandes.

Código fuente

Mientras creamos un nuevo repositorio para este tipo de proyectos, puedes descargarte el código desde el mensaje original en la lista de correo.

///////////////////////////////////////////////////////////////////////////////
////////   CONTROL DE WATCHDOG REMOT PER A REINICIAR NODES GUIFI.NET
////////
////////                    Josep Figueras i Franch
 ////////
////////                          Gener - 2011
////////
////////                           V1.01 BETA
 ////////
////////
////////
////////             * Descripció del Pinout - PIC16F877 *
////////
////////               ---------------------------------
////////
////////          RA0 = Out Relé per atacar al botó de Reset
////////
////////          RA1 =
 ////////
////////          RA2 =
 ////////
////////          RA3 =
 ////////
////////          RA4 =
 ////////
////////          RA5 =
 ////////
////////          RB0 =
 ////////
////////          RB1 =
 ////////
////////          RB2 =
 ////////
////////          RB3 =
 ////////
////////          RB4 =
 ////////
////////          RB5 =
 ////////
////////          RB6 =
 ////////
////////          RB7 =
 ////////
////////          RC0 =
 ////////
////////          RC1 =
 ////////
////////          RC2 =
 ////////
////////          RC3 =
 ////////
////////          RC4 =
 ////////
////////          RC5 =
 ////////
////////          RC6 = TX RS-232C
////////
////////          RC7 = RX RS-232C
////////
////////          RD0 =
 ////////
////////          RD1 =
 ////////
////////          RD2 =
 ////////
////////          RD3 =
 ////////
////////          RD4 =
 ////////
////////          RD5 =
 ////////
////////          RD6 =
 ////////
////////          RD7 =
 ////////
////////          RE0 =
 ////////
////////          RE1 =
 ////////
////////          RE2 =
 ////////
///////////////////////////////////////////////////////////////////////////////
// END RESUM PINOUT //
 
#include <16F877A.h>
//#define use_portb_kbd
 
#define FALS 0
#define CERT 1
#define ON 1
#define OFF 0
#define DEFECTE 69
#define START 0xFF
#define PintaMenu 222
 
//Opcions de la màquina d'estats de la RTCC INT
#define Dorm 1
 
#use delay(clock = 20000000)                                     //Rellotge
fixat a 20 MHz
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)
#fuses HS,NOWDT,PROTECT,NOLVP                                   //Treballem
amb un cristall d'alta velocitat de 20MHz [HS = High Speed]
 
//desactivem el Watchdog i protegim el codi
 
//Tot seguit donem noms mnemotècnics a les @'s dels ports utilitzats
//Aquestes direccions les trobem a la pàgina 8 del datasheet (mapa de
memòria)
#byte      port_a = 05                                          //Direcció
del port A
#byte      port_b = 06                                          //Direcció
del port B
#byte      port_c = 07                                          //Direcció
del port C
 
#include <flex_lcd.h>
//#include <kbd.c>
 
////////////////////INICI DE LES VARIABLES GLOBALS////////////////////
//static BYTE MostraSIO;                                        //Variable
per enviar les mostres cap al S.O.
static int OpcioRTCC;                                           //Variable
per a la màquina d'estats de la RTCC
static char SerialKey = ' ';                                    //Variable
on hi guardo el caràcter rebut per la SIO
static int EstatResetNode;                                      //Flag que
indica si el relé que activa el reset del servidor/node està connectat o
desconnectat
 
//Flags de control
static int ExecutaComanda;                                      //Flag que
executa l'acció escollida per l'usuari quan apreta la tecla 0 o comfirma
per RS-232
////////////////////FI DE LES VARIABLES GLOBALS////////////////////
 
 
////////////////////INICI DELS PROTOTIPUS////////////////////
void Init (void);
void NetejaLCD (void);
void BucleInfinit (void);
int ConverteixCaracterAEnter(char * caracter);
////////////////////FI DELS PROTOTIPUS////////////////////
 
 
////////////////////INICI DE LES INTERRUPCIONS////////////////////
#int_rda
void RDA_isr(){
SerialKey = 0x00;
if (kbhit()) {
SerialKey = getchar();
if(SerialKey != 0x00){
switch (SerialKey) {
case 'a':
//Activo el reset del Servidor/Node
delay_ms(20);
output_hight (PIN_A0);
EstatResetNode = ON;
ExecutaComanda = CERT;
break;
 
case 'b':
//Desactivo el reset del Servidor/Node
delay_ms(20);
output_low (PIN_A0);
EstatResetNode = OFF;
ExecutaComanda = CERT;
break;
 
case 'c':
//Envio pel port sèrie quin és l'estat REAL del relé de Reset del
Servidor/Node
delay_ms(20);
printf("%d",EstatResetNode);
ExecutaComanda = CERT;
break;
 
case 'd':
//Envio la cadena "OK" per dir que el sistema PIC està viu
delay_ms(20);
printf("OK");
break;
 
case 'e':
//Envio pel port sèrie un missatge de benvinguda per comprovar que tinc
comunicació amb el PIC
delay_ms(20);
printf("\nHola, la comunicacio amb el microcontrol.lador funciona!\n");
ExecutaComanda = CERT;
break;
}
}
}
}
 
 
#int_RTCC
void RTCC_isr(){
switch (OpcioRTCC) {
case Dorm:
//No faig res de res dins de la RTCC-INT
break;
}
}
////////////////////FI DE LES INTERRUPCIONS////////////////////
 
 
////////////////////INICI DEL CODI DE L'APLICACIÓ////////////////////
void Init (void) {
//Inicialització
//Tot el port A i el port E és de sortida
set_tris_a(0x00);
set_tris_e(0x00);
 
//Desactivo tots els relés de sortida (Condicions inicials)
output_low (PIN_A0);
output_low (PIN_A1);
output_low (PIN_A2);
 //Desactivo els conversors interns del PIC
setup_adc_ports(NO_ANALOGS);
  setup_adc(ADC_OFF);
 
//Desactivo el control I2C
  setup_spi(FALSE);
 
//Configuro els timers
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
 
//Activo la interrupció del port RS-232
enable_interrupts(int_rda);
 //Activo la interrupció RTCC
enable_interrupts(INT_RTCC);
 
//Activo les interrupcions
enable_interrupts(GLOBAL);
 
//Programo la RTCC perque no enviï els senyals de control a la memòria,
etc...
OpcioRTCC = Dorm;
 
//Espero 100 mseg. perque s'estabilitzi tot el sistema
delay_ms(100);
}
 
 
////////////////////INICI DEL BUCLE INFINIT////////////////////
void BucleInfinit (void) {
 for ( ; ; ) {
//Eternament el pic no farà res fins que rebi una interrupció.
//D'això se'n diu tenir bona vida...
sleep(1);
}
}
////////////////////FI DEL BUCLE INFINIT////////////////////
 
 
void main(void) {
   Init();
   BucleInfinit();
}
 
int ConverteixCaracterAEnter(char * caracter) {
//Funció "tonta" que converteix els caràcters Ascii als seus corresponents
valors enters
return (caracter - 48);
}

Posibles mejoras

  • Conexión con módem GSM con salida RS-232 (aunque son bastante caros: ejemplo en eBay)
  • Conexión con un teléfono móvil con una tarjeta SIM y uso de códigos DTMF (más barato, pero necesita normalmente terminales antiguos).
  • Versión Arduino
Herramientas personales