Diferencia entre revisiones de «GuifiReset»

De Guifi.net - Wiki Hispano

(Esquemáticos)
(Código fuente)
Línea 33: Línea 33:
 
== Código fuente ==
 
== Código fuente ==
 
Mientras creamos un nuevo repositorio para este tipo de proyectos, puedes descargarte el código desde el [https://lists.guifi.net/pipermail/guifi-rdes/2012-January/022659.html mensaje original] en la lista de correo.
 
Mientras creamos un nuevo repositorio para este tipo de proyectos, puedes descargarte el código desde el [https://lists.guifi.net/pipermail/guifi-rdes/2012-January/022659.html mensaje original] en la lista de correo.
 +
 +
<pre>
 +
///////////////////////////////////////////////////////////////////////////////
 +
////////  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);
 +
}
 +
</pre>
  
 
[[Categoría:DIY]]
 
[[Categoría:DIY]]
 
[[Categoría:Electrónica]]
 
[[Categoría:Electrónica]]

Revisión de 23:18 20 ene 2012

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.

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

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);
}
Herramientas personales