lunes, 6 de noviembre de 2017

Boton de apagado para OPENELEC- Raspberry-pi

Hola.. cuanto tiempo!! En esta ocasión os presento una adaptación de un circuito muy simple para poder apagar la raspberry-pi de forma ordenada, sin que se corrompan los discos, con OPENELEC.




El esquema es el siguiente: 
Esquema


Luego nos faltan dos archivos. El primero es el script en python que hace un pool al GPIO4 cada segundo. Por lo tanto hay que pulsar por más de un segundo hasta que se apague.

Ambos archivos se ubican en /storage/.config/
El primer archivo se llama softshut.py

# Import the modules to send commands to the system and access GPIO pins
#from subprocess import call
import os
import sys
import time
sys.path.append('/storage/.kodi/addons/python.RPi.GPIO/lib')
import RPi.GPIO as gpio

gpio.setmode(gpio.BOARD) # Set pin numbering to board numbering
gpio.setup(7, gpio.IN) # Set up pin 7 as an input

while True:
    time.sleep(1)
    if(gpio.input(7)):
             os.system("echo 0 >/sys/class/leds/led1/brightness")
             os.system("halt")

       
El otro es autostart.sh que si no existe lo creais. Sirve para lanzar el script anterior al inicio.

(
python /storage/.config/softshut.py
)&


Mas info sobre autostart aqui: http://wiki.openelec.tv/index.php/Autostart.sh


Foto de como queda


Funcionamiento:

Antes de desconectar pulsar por un segundo. Veremos que los leds parpadean hasta que quedan fijos. en ese momento es seguro apagar.

Basado en:
http://www.raspberry-pi-geek.com/Archive/2013/01/Adding-an-On-Off-switch-to-your-Raspberry-Pi





viernes, 11 de octubre de 2013

Coche barato, radio cara. Adaptador PWM servo a motor 2/2

Hola.

Lo prometido es deuda, asi que aqui tenemos la segunda parte de este proyecto.

En este vídeo podeis ver cómo es el control de la aceleración del coche, que antes era encendido/apagado y ahora acelera más cuanto más movemos la palanca:


El programa está hecho en CCS y es muy simple. Se divide en dos partes: 1) la lectura del pulso del servo a través del puerto B y 2) la generación de PWM proporcinal a la velocidad, a través del puerto A y B. 1) Lectura del pulso del servo. Esta parte es la más crítica ya que hemos de leer con precisión los pulsos que irían a un servo y convertirlo en una numeración. Para eso usaremos el timer0 del pic. Préviamente hemos calculado los "ticks" que contará este timer y cómo ajustamos el preescaler. Por ejemplo, para el cristal de 4Mhz, sabiendo que un servo en reposo o 50% da un pulso de 1,5ms. xtal=4 incremento:Xtal/4=1us x 8(preescaler) =8us Entonces el contador contará para: 1ms: 1,5ms/8us = 125 1,5ms: 1,5ms/8us = 187 2ms: 1,5ms/8us = 250 Hemos escogido el preescaler de 8 para abarcar esta horquilla entre 0 y 255.
  1. #include <16F84.H>
  2. #FUSES NOWDT      //No Watch Dog Timer
  3. #FUSES HS      //para cristal de 6MHz
  4. #FUSES PUT     //power up timer habilitado
  5. #FUSES NOPROTECT//lectura habilitada del codigo del pic
  6. //#use delay(clock=4000000) // 4 MHz OSC
  7. //#use delay(clock=3579000) // 4 MHz OSC
  8. #use delay(clock=6000000) // 6 MHz OSC
  9. #USE FAST_IO (A)
  10. #USE FAST_IO (B)
  11. #define PIN_SERVOi1     PIN_B4
  12. #define PIN_SERVOi2     PIN_B5
  13. #define PIN_SERVOi3     PIN_B6
  14. #define PIN_SERVOi4     PIN_B7
  15. #define PIN_MOTOR1R     PIN_A0
  16. #define PIN_MOTOR1L     PIN_A1
  17. #define PIN_MOTOR2R     PIN_A2
  18. #define PIN_MOTOR2L     PIN_A3
  19. #define PIN_MOTOR3R     PIN_B0
  20. #define PIN_MOTOR3L     PIN_B1
  21. #define PIN_MOTOR4R     PIN_B2
  22. #define PIN_MOTOR4L     PIN_B3
  23. #define PIN_LED       PIN_A4
  24. /*
  25. xtal=3,57   incremento= 1.117 x 8 = 8,94 us
  26. 1.5ms= 167
  27. ULIMIT= 167 +10
  28. LLIMIT= 167 -10
  29. xtal=558k   inc= 7.168 x 1
  30. =195
  31. xtal=6 inc= 0,666  x 16 =10.66666
  32. =140
  33. */
  34. #define ULLIMIT 140
  35. #define ULIMIT 150
  36. #define LLIMIT 130
  37. int8 tempo,ledco;
  38. int8 timerco1,motor1L,motor1R;
  39. int8 timerco2,motor2L,motor2R;
  40. int8 timerco3,motor3L,motor3R;
  41. int8 timerco4,motor4L,motor4R;
  42. int8 scounter;
  43. int8 semaforo;
  44. boolean ledb;
  45. //**********************************************************************************
  46. //**********************************************************************************
  47. #INT_RB
  48. void interrupcionRB() {
  49. SWITCH(input_b()&0xF0){
  50.     case 0b00010000:set_timer0(0); semaforo=1;break;
  51.     case 0b00100000:set_timer0(0); semaforo=2;break;
  52.     case 0b01000000:set_timer0(0); semaforo=3;break;
  53.     case 0b10000000:set_timer0(0); semaforo=4;break;
  54.    
  55.     case 0:
  56.         switch (semaforo){
  57.        
  58.             case 1:timerco1=get_timer0();semaforo=0;ledco++;break;
  59.             case 2:timerco2=get_timer0();semaforo=0;ledco++;break;
  60.             case 3:timerco3=get_timer0();semaforo=0;ledco++;break;
  61.             case 4:timerco4=get_timer0();semaforo=0;ledco++;break;
  62.    
  63.         }
  64.     default:
  65.         semaforo=0;
  66.    
  67. }
  68. //**********************************************************************************
  69. //******************************  M A I N  *****************************************
  70. //**********************************************************************************
  71. void main(){
  72.    
  73.    set_tris_a(0);  // todo salida
  74.    set_tris_b(0b11110000);  // todo salida rb4,6,7 entrada
  75.    output_a(0);
  76.    output_b(0);
  77.    output_high(PIN_LED);
  78.    
  79.      
  80.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);   //activamos timer0 como interno
  81.    set_timer0(0);
  82.     motor1L,motor1R=0;
  83.     motor2L,motor2R=0;
  84.     motor3L,motor3R=0;
  85.     motor4L,motor4R=0;
  86.    
  87.     timerco1,timerco2,timerco3,timerco4=ULLIMIT;
  88.    enable_interrupts(INT_RB);
  89.    enable_interrupts(GLOBAL);
  90.    
  91.    
  92.    
  93.    
  94.    for(ledco=0;ledco<5;ledco++) {output_bit(PIN_LED,ledb);
  95.     ledb=!ledb;
  96.     delay_ms(500);
  97.    
  98.    }
  99.  
  100. while(1){  //bucle infinito  
  101.     for(tempo=0;tempo<=100;tempo++){
  102.     // PWM DEL MOTOR
  103.    
  104.     //evaluamos aqui para no perder tiempo
  105.    
  106.     if(tempo==95 ){
  107.         if(ledco++ >254){
  108.             output_bit(PIN_LED,ledb);
  109.             ledb=!ledb;
  110.             ledco=0;
  111.         }      
  112.     }else if(tempo==96 ){
  113.        
  114.         if(timerco1 > ULIMIT ){ motor1R=(--timerco1-ULIMIT)*3;motor1L=0;}
  115.         else if(timerco1 < LLIMIT) {motor1L=(LLIMIT-timerco1++)*3;motor1R=0;}
  116.         else{motor1R=0;motor1L=0;}
  117.     }else if(tempo==97 ){
  118.    
  119.         if(timerco2 > ULIMIT ){ motor2R=(--timerco2-ULIMIT)*3;motor2L=0;}
  120.         else if(timerco2 < LLIMIT) {motor2L=(LLIMIT-timerco2++)*3;motor2R=0;}
  121.         else{motor2R=0;motor2L=0;}
  122.        
  123.     }else if(tempo==98 ){
  124.    
  125.         if(timerco3 > ULIMIT ){ motor3R=(--timerco3-ULIMIT)*3;motor3L=0;}
  126.         else if(timerco3 < LLIMIT) {motor3L=(LLIMIT-timerco3++)*3;motor3R=0;}
  127.         else{motor3R=0;motor3L=0;}
  128.        
  129.     }else if(tempo==99 ){
  130.    
  131.         if(timerco4 > ULIMIT ){ motor4R=(--timerco4-ULIMIT)*3;motor4L=0;}
  132.         else if(timerco4 < LLIMIT) {motor4L=(LLIMIT-timerco4++)*3;motor4R=0;}
  133.         else{motor4R=0;motor4L=0;}     
  134.        
  135.     }
  136.    
  137.    
  138.         output_bit(PIN_MOTOR1R,(motor1R >tempo));
  139.         output_bit(PIN_MOTOR1L,(motor1L >tempo));
  140.        
  141.         output_bit(PIN_MOTOR2R,(motor2R >tempo));
  142.         output_bit(PIN_MOTOR2L,(motor2L >tempo));
  143.        
  144.         output_bit(PIN_MOTOR3R,(motor3R >tempo));
  145.         output_bit(PIN_MOTOR3L,(motor3L >tempo));
  146.        
  147.         output_bit(PIN_MOTOR4R,(motor4R >tempo));
  148.         output_bit(PIN_MOTOR4L,(motor4L >tempo));
  149.                
  150.        
  151.         delay_us(100);
  152.        
  153.    
  154.     } //bucle tempo
  155.    
  156.    
  157. } //end while  
  158. }

jueves, 16 de agosto de 2012

Adaptador KKL-VAGCom 409 para diagnosis OBD

Después de varias pruebas y navegar aquí y allá he conseguido un esquemita para fabricarse un interface KKL VAGCom 409. El motivo era poder conectarme a mi coche a través de OBD y borrar varias alarmas, concretamente la pesada y recurrente del AIRBAG de mi FIAT.

En el tema software podéis usar el FIAT ECUSCAN, ahora llamado Multiecuscan que en su versión free servirá para el propósito. No voy a entrar en el funcionamiento del programa que es bastante fácil y podéis encontrar amplia información en Internet.




Proto-tipo


Uno de los quebraderos de cabeza ha sido configurar el puerto COM con el usb ya que el Windows no es demasiado amigable y los portátiles modernos ya no lo traen, entonces es recomendable comprarse el adaptador USB-RS232. Recomiendo abrir el "administrador de dispositivos" y observar los puertos, entonces conectar el adaptador USB-RS232 y ver que COM aparece. Luego ya podemos configurar el FIATECUSCAN con ese puerto COM.
Aunque se llame KKL VAGCom 409 no se usa la línea L, solo la K. En este caso el airbag para este modelo de FIAT se conecta en el pin 3 pero otros dispositivos pueden conectarse en los pin's 7 o 9. No lo he probado en otras marcas. Además sólo necesitamos el pin 16 para los 12V del coche y el pin 4 o 5 de negativo.

El esquema es bastante sencillo, he añadido un led para visualizar la actividad de la línea K. La resistencia de 200K alimenta el zener de 5,1V que a su vez alimenta el MAX232, por eso recomiendo que sea de 1/2W pues la de 1/4 se calienta un poco. También se puede usar un 7805 para esto.


https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5Y8BIlOCYz9Vw4-32NOZRJI-dBfuWbGACEzFvQEYI6ObvDNyUil2IYqRg_ULUdp3NNDdqEn7_JXM5NRxKels-cNiOcDdTp43h4WH3SekrP4xb2jA3S3Xtz09yHTAHjmaYxbdh0MoCF3g/s1600/KKL-Vagcom+409.png
KKL-VAGCOM

El esquema es un poco rústico y carece de aislamientos, por eso os recomiendo usar un portátil con su batería, sobretodo NO usar alimentadores de esos que convierten 12 a 19 para alimentar el PC, tampoco conviene que el PC toque partes metálicas del coche. 
Tampoco me responsabilizo del daño que podáis hacer a la ECU del coche, al PC o a vosotros mismos... Estamos manipulando el AIRBAG y hay una remota posibilidad que este salte!

Acabemos de contar la historia.. he llegado aquí después de comprarme un adaptador ELM327 chino y comprobar que justamente para el airbag necesitaba el KKL VAGCom. Herido mi orgullo por el tremendo error no concibo comprarme otro cable y esperar otro mes a que venga desde China, además he podido reutilizar el conector OBD y el interface serie bluetooth me lo estoy mirando de reojo para otros proyectos.
Después de conectarme al coche tampoco he podido borrar las alarmas.... A parte del fallo del airbag del asiento, falla el lateral derecho, el izquierdo....

Si te ha sido de utilidad esta entrada o si quieres aportar algo por favor deja tus comentarios..

martes, 15 de noviembre de 2011

Coche barato, radio cara. Adaptador PWM servo a motor 1/2

Hola.
Basicamente queremos controlar motores con una radio sin usar los servos.
Con un coche de radiocontrol barato que evidéntemente trae una radio muy sencilla basada en el famoso "superchip" no tenemos ni mucho alcance ni control, ya que la transmisión es del tipo 1 o 0, osea encendido o apagado, ¿podemos adaptar una radio con servos? si con un control electrónico adecuado.

Nuestro proyecto consiste en sustituir todo o parte del control existente del coche. Finalmente he conservado la parte de actuación de los motores compuesta por los puentes H y he implementado los controles con un PIC. El PIC elegido es el famoso 16F84 pero podemos usar tamben un 12F629 o 683, en ese caso sólo dispondremos de 2 canales y con el 16F84 aprovechamos hasta 4.

El coche dispone de un motor de tracción trasera y otro de dirección, accionados por puentes H de transistores, entonces por cada motor hemos de generar 2 señales PWM  una por cada sentido de giro del motor.


El esquema esta adaptado para cuatro canales, aunque sólo usamos dos. Por lo demás no puede ser más sencillo (podemos simplificar si utizamos un PIC12 de 8 pins con oscilador interno..)

Al ser un control PWM conseguimos que el coche acelere poco a poco según giramos la palanca , no como el coche original que iba a trompicones.

Una vez todo montado, se sella bien con cola para evitar que se desmonte con los golpes y traqueteo. La radio se fija con gomas para poder retirarla caso de destrozar el coche.

En próximas entradas incluiré el código en C del PIC y el archivo .HEX


A disfrutarlo!

lunes, 14 de noviembre de 2011

Bienvenidos a Xusco-Invents

Un blog sobre tecnologia, electrónica, telefonia, inventos y aplicaciones.

Cosas xuscas e ingeniosas, para entretenerse .. o no?