Etiquetas

555 74HC04 74HC14 74HC165 74LS04 acentos ADC10 Amstrad archivo arduino aristóteles armbian array ass at backup base64 bash Basho bc beethoven Biblia blog bucle c c++ c++11 c++17 C005 cadena Carmina Burana casting CD4017 CD4040 Cine clases Colores connect Consolación a Helvia Consolación a Marcia Consolación a Polibio constante corsair CPC Cristal 32Khz css cursor mouse cut daemon date dead keys Debian directorio disco duro DS32kHz electricidad Electrónica ensamblador entryList epicureismo Estadística estoicismo felicidad ffmpeg filePath filosofia Filosofía firefox flac for fstab funcion Gargantúa gastronomía gilgamesh Ginott gmp gpt grep gtts Hobbes hotkeys html imagemagick inline Javascript kde kernel modulos latex ldr lib-notify Linux Literatura ludoteca macro mapa de bits Matroska mega Microsoft Word Milan Kundera mkvextract mkvinfo mount mp3 mplayer MSP430 msp430F5529 MSP432 Multimedia Musica oop orange_pi pato PIR PL9823 Platón poesía POO en C++ pulseaudio puntero PWM pygame pyqt python QAction qApp QApplication QByteArray QDialog Qdir QFile QFileDialog QImage qlabel QList QListWidget QMessagebox QMouseEvent qpainter QPalette QPixmap QProcess QRegularExpression QRegularExpressionMatchIterator QString QStringList Qt qt5 QToolbar quijote QVector qwidget R Rabelais ratón relé Resonador cerámico samba San Agustín screen Séneca signal slot smart smartctl sox srt static const stdarg.h subtítulos Symbian tar teléfonos móviles temperatura temperatura cpu Temporizador tesseract Timer timestamp Trigonometría tts tutorial uid unicode user USI va_arg va_end va_list va_start velocidad ventilador Voltaire wallpaper xboxdrv xinput xrandr Z80 zip

domingo, febrero 01, 2015

Comprimir en paralelo en Linux

Para comprimir:
tar -c --use-compress-program=pigz -f /tmp/salida.tgz dir1 dir2 archivo1 archivo2

Para descomprimir:
tar -xvzf /tmp/salida.tgz

martes, enero 27, 2015

Un módulo PIR


El integrado es el BISS0001 datasheet.

domingo, enero 18, 2015

Importar archivos en R

Este resumen no está disponible. Haz clic en este enlace para ver la entrada.

jueves, octubre 16, 2014

MSP430 y encoder rotativo



Giro en sentido horario

Giro en sentido anti-horario

Conexión:
P2.0 - Canal A
P2.1 - Canal B
Para evitar rebotes añadir condensadores de 0.1 uF.

Funcionamiento:
Las entradas 2.0 y 2.1 tienen activos las resistencias pull-up. Además, la 2.0 tiene activa la interrupción en el flanco de bajada.

#pragma vector=PORT2_VECTOR
__interrupt void PORT2_ISR_HOOK(void)
{
if ((P2IFG & ROTARY_A) == ROTARY_A) {
if ((P2IN & ROTARY_B) == ROTARY_B) {
 //Giro en sentido anti-horario
} else {
 //Giro en sentido horario
}
P2IFG &= ~ROTARY_A;
}
}


martes, septiembre 23, 2014

Obteniendo unidades, decenas, centenas... en python

#!/usr/bin/python
# -*- coding:utf8 -*-

# Descompone un numero en unidades, decenas, centenas y unidades de millar.

print "Introduce el número: "
numero = int(raw_input ())

umil = numero / 1000
tmp = numero % 1000

centenas = tmp / 100
tmp = tmp % 100

decenas = tmp / 10
unidades = tmp % 10

print "Unidades de millar: %i" % umil
print "Centenas: %i" % centenas
print "Decenas: %i" % decenas
print "Unidades: %i" % unidades

viernes, agosto 15, 2014

Can't help falling in love


jueves, julio 17, 2014

Temporziador 555. Delay on, timer off

Delay on:
http://555-timer.clarkson-uk.com/operation/frames3.html

Timer off:
http://www.eleinmec.com/article.asp?4

miércoles, junio 25, 2014

miércoles, mayo 21, 2014

Apuntes sobre aritmética con bash y bc

Aritmética sencilla con bash
VALOR1="123"
VALOR2="456"
let "SUMA=${VALOR1}+${VALOR2}"

División con decimales, imposible de hacer con bash, hay que utilizar bc
PROPORCION=`bc <<< "scale=10; ${VALOR1}/${VALOR2}"`

Conversión de un número decimal a entero con bc
ENTERO=`"bc <<< "(${VALOR1}*${VALOR2}+0.5)/1"`

Creando wallpapers en doble pantalla con bash e imagemagick

1. Descripción de las pantallas
  • Pantalla principal: 22 pulgadas, 1920x1080.
  • Pantalla secundaria: 19 pulgadas, 1440x900.
  • Físicamente la pantalla secundaria esta 1cm por debajo de la principal.
  • La densidad de pixels de ambas pantallas es diferente, por lo que hay que hacer algunos cálculos para que las imágenes encajen.
2. Cálculo del tamaño de las imágenes.
  • La pantalla de 22 pulgadas, 1920x1080 tiene un tamaño de 477mm x 269 mm (4 pixels por mm)
  • La pantalla de 19 pulgadas, 1440x900 mide 408mm x 255mm (3.5 pixels por mm)
  • Para se vea bien la imagen de la pantalla de 19 pulgadas debe medir:
  •  (1440 * 4 / 3.5) x (900 * 4 / 3.5)

3. Descripción del proceso
  • La imagen original es de 16 megapixels (4608x3456)
  • Editar la imagen con gimp y recortarla con una proporción fija de 3360x1180. (1920+1440 de ancho y 1080 más 100 pixels de margen).
  • Exportarla como TIFF para evitar pérdidas por compresión.
  • Editar las variables del script según convenga. El resultado son dos imágenes (1920x1080 y 1440x900) que encajan una con la otra.

Nota: El script no está optimizado para que sea más fácil de entender y modificar.

#!/bin/bash

################################################
### Variables que siempre hay que modificar  ###

# RECUERDA: La imagen a recortar es con la proporción 3360:1080
FILENAME="pic04.tiff"

#Ajuste de la imagen de la pantalla 1 para que encaje con la
#de la pantalla 2. 
SCR1_OFFSET="60"

### Variables que tal vez haya que modificar ###

# El añadido al alto real
VIRTUAL_EXPANSION="100"

#Tamaño real de las pantallas
SCR1_WIDTH="1920"
SCR1_HEIGHT="1080"

# La pantalla es 1440x900 pero al tener diferente
# dpi hago un ajuste en el tamaño de la imagen
SCR2_WIDTH="1646"
SCR2_HEIGHT="1029"
#SCR2_WIDTH="1440"
#SCR2_HEIGHT="900"


## A partir de aquí ya no hay que modificar nada ##
###################################################

#Tamaño virtual de las pantallas
#Asumo que la pantalla 1 siempre es mayor que la 2
let "VIRTUAL_HEIGHT=$SCR1_HEIGHT+$VIRTUAL_EXPANSION"

TEMP_FILE1A="/tmp/1920x1080_tmpa.tiff"
TEMP_FILE2A="/tmp/1440x900_tmpa.tiff"

TEMP_FILE1B="/tmp/1920x1080_tmpb.tiff"
TEMP_FILE2B="/tmp/1440x900_tmpb.tiff"

#TEMP_FILE1C no es necesario
TEMP_FILE2C="/tmp/1440x900_tmpc.tiff"

FINAL_FILE1="/tmp/1920x1080.jpg"
FINAL_FILE2="/tmp/1440x900.jpg"


#Calcular tamaño total del escritori
let "VIRTUAL_WIDTH=$SCR1_WIDTH+$SCR2_WIDTH"

echo -e "Obteniendo el tamaño de la imagen..."

# Averiguar tamaño de la imagen
IMG_WIDTH=`identify $FILENAME | cut -d ' ' -f3 | cut -d 'x' -f1`
IMG_HEIGHT=`identify $FILENAME | cut -d ' ' -f3 | cut -d 'x' -f2`


# Calcular proporcion del escritorio respecto de la imagen
# Usando bc para obtener un resultado con decimales
PROPORTION=`bc <<< "scale=10; $IMG_WIDTH/$VIRTUAL_WIDTH"`


#Calculo del tamaño de los recortes teniendo en cuenta la proporción
#El resultado es un entero por la extraña operación añadida
W1_WIDTH=`bc <<< "($SCR1_WIDTH*$PROPORTION+0.5)/1"`
W2_WIDTH=`bc <<< "($SCR2_WIDTH*$PROPORTION+0.5)/1"`

W1_HEIGHT=`bc <<< "($VIRTUAL_HEIGHT*$PROPORTION+0.5)/1"`

echo -e "Preparando imágenes..."

#cortar imagenes
convert ${FILENAME} -crop ${W1_WIDTH}x${W1_HEIGHT}+0+${IMG1_OFFSET} ${TEMP_FILE1A}
convert ${FILENAME} -crop ${W2_WIDTH}x${W1_HEIGHT}+${W1_WIDTH}+${IMG2_OFFSET} ${TEMP_FILE2A}

echo -e "Redimensionando imágenes..."

#redimensionar
convert ${TEMP_FILE1A} -resize ${SCR1_WIDTH}x${VIRTUAL_HEIGHT} ${TEMP_FILE1B}
convert ${TEMP_FILE2A} -resize ${SCR2_WIDTH}x${VIRTUAL_HEIGHT} ${TEMP_FILE2B}

echo -e "Guardando imágenes..."

#Recorte final
let "SCR1_SOBRANTE=${VIRTUAL_EXPANSION}-${SCR1_OFFSET}"
convert ${TEMP_FILE1B} -crop ${SCR1_WIDTH}x${SCR1_HEIGHT}+0+${SCR1_SOBRANTE} $FINAL_FILE1

let "SCR2_SOBRANTE=$VIRTUAL_HEIGHT-$SCR2_HEIGHT"
convert ${TEMP_FILE2B} +repage -crop ${SCR2_WIDTH}x${SCR2_HEIGHT}+0+${SCR2_SOBRANTE} ${TEMP_FILE2C} 

#redimensionado final en la segunda pantalla
convert ${TEMP_FILE2C} -resize 1440x900\! ${FINAL_FILE2}

echo -e "\nSumario:"
echo -e "DATOS DE LA IMAGEN"
echo -e "El ancho es $IMG_WIDTH"
echo -e "El alto es $IMG_HEIGHT"
echo
echo -e "DATOS DEL ESCRITORIO"
echo -e "Ancho total: $VIRTUAL_WIDTH"
echo -e "Proporción entre la imagen y el escritorio: $PROPORTION"
echo
echo -e "Terminado."

viernes, mayo 02, 2014

Conexión del arduino mini pro al conversor UART TTL cp2102 de 6 pins

El CP2102 incluye el pin DTR que resetea automáticamente el arduino cuando se lo programa.




Arduino     CP2102
GND ------- GND
VCC ------- +5V
RXI ------- TXD
TXD ------- RXD
GRN ------- DTR 

Tutorial para usar el conversor de 5 pins

jueves, febrero 20, 2014

CD4017 con 4 LEDs


CD4040 como divisor de frecuencia


PIN FRECUENCIA
10  INPUT
 9  INPUT/2
 7  INPUT/4
 6  INPUT/8
 5  INPUT/16
 3  INPUT/32
 2  INPUT/64
 4  INPUT/128
13  INPUT/256
12  INPUT/512
14  INPUT/1024
15  INPUT/2048
 1  INPUT/4096

domingo, enero 05, 2014

jueves, diciembre 26, 2013

74HC04 vs 74LS04 vs 74HC14

Una Puerta lógica:
Flanco de subida:
Flanco de bajada:

Tres puertas lógicas en serie:
Flanco de subida:
Flanco de bajada:

lunes, diciembre 23, 2013

miércoles, octubre 30, 2013

PWM con el MSP430


  • El contador del timer se configura para que cuente hasta 200.
  • De 0 hasta 20 la salida está high. El resto hasta 200 está low.
  • Al llegar a 200 se ejecuta la interrupción TIMER0_A0_VECTOR. 
  • La salida está en P 1.2.

Configuración de la salida:
P1SEL = BIT2;

Configuración del timer:
    /*
     * TACCTL0, Capture/Compare Control Register 0
     *
     * CM_0 -- No Capture
     * CCIS_0 -- CCIxA
     * ~SCS -- Asynchronous Capture
     * ~SCCI -- Latched capture signal (read)
     * ~CAP -- Compare mode
     * OUTMOD_0 -- PWM output mode: 0 - OUT bit value
     *
     * Note: ~ indicates that has value zero
     */

    TACCTL0 = CM_0 + CCIS_0 + OUTMOD_0 + CCIE;

Configuración del PWM:
    /*
     * TACCTL1, Capture/Compare Control Register 1
     *
     * CM_0 -- No Capture
     * CCIS_0 -- CCIxA
     * ~SCS -- Asynchronous Capture
     * ~SCCI -- Latched capture signal (read)
     * ~CAP -- Compare mode
     * OUTMOD_7 -- PWM output mode: 7 - PWM reset/set
     *
     * Note: ~ indicates that has value zero
     */

    TACCTL1 = CM_0 + CCIS_0 + OUTMOD_7;

Fijar el contador en 200, la transición del high a low al llegar a 20:
TACCR0 = 200;
TACCR1 = 20;

Configurar la fuente del reloj:
    /*
     * TACTL, Timer_A2 Control Register
     *
     * TASSEL_1 -- ACLK
     * ID_0 -- Divider - /1
     * MC_1 -- Up Mode
     */

    // Usando ACL 12khz
    // TACCR0 : 1Seg = 12000
    // TACCR1 : 99% -> 198 (99% hight, 1% low)
    //          50% -> TACCR0 /2


    TACTL = TASSEL_1 + ID_0 + MC_1;

El código a ejecutar en la interrupción al llegar a 200:
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A0 (void){
P1OUT ^= BIT0;
}


lunes, octubre 07, 2013

DS32kHz conectado al MSP430

Las luces del coche fantástico con 4 leds. El bucle principal del programa avanza un led en cada ciclo y entra en LPM4. La interrupción del Timer se encarga de reanudar la ejecución.


src/grace/GPIO_init.c
P1.0 tiene que configurarse como TA0CLK.

/*
 *  ======== GPIO_graceInit ========
 *  Initialize MSP430 General Purpose Input Output Ports
 *
 *  The GPIO registers should be set in a specific order:
 *     PxOUT
 *     PxSEL or PxSELx
 *     PxDIR
 *     PxREN
 *     PxIES
 *     PxIFG
 *     PxIE
 *
 *     This will ensure that:
 *         - IFG doesn't get set by manipulating the pin function, edge
 *           select, and pull-up/down resistor functionalities (see
 *           Section 8.2.6 of the MSP430 User's manual)
 *         - Glitch-free setup (configuring the OUT register _before_
 *           setting the pin direction)
 *         - Pull-up/pull-down resistor enable with the correct direction
 *           (.up. vs. .down.)
 */
void GPIO_graceInit(void)
{
    /* USER CODE START (section: GPIO_graceInit_prologue) */
    /* User initialization code */
    /* USER CODE END (section: GPIO_graceInit_prologue) */

    /* Port 1 Output Register */
    P1OUT = 0;

    /* Port 1 Port Select Register */
    P1SEL = BIT0;

    /* Port 1 Direction Register */
    P1DIR = BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7;

    /* Port 1 Interrupt Edge Select Register */
    P1IES = 0;

    /* Port 1 Interrupt Flag Register */
    P1IFG = 0;

    /* Port 2 Output Register */
    P2OUT = 0;

    /* Port 2 Port Select Register */
    P2SEL &= ~(BIT6 + BIT7);

    /* Port 2 Direction Register */
    P2DIR = BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7;

    /* Port 2 Interrupt Edge Select Register */
    P2IES = 0;

    /* Port 2 Interrupt Flag Register */
    P2IFG = 0;
}


src/grace/Timer0_A3_init.c
/*
 *  ======== Timer0_A3_graceInit ========
 *  Initialize MSP430 Timer0_A3 timer
 */
void Timer0_A3_graceInit(void)
{
    /* 
     * TA0CCTL0, Capture/Compare Control Register 0
     * 
     * CM_0 -- No Capture
     * CCIS_0 -- CCIxA
     * ~SCS -- Asynchronous Capture
     * ~SCCI -- Latched capture signal (read)
     * ~CAP -- Compare mode
     * OUTMOD_0 -- PWM output mode: 0 - OUT bit value
     * 
     * Note: ~<BIT> indicates that <BIT> has value zero
     */
    TA0CCTL0 = CM_0 + CCIS_0 + OUTMOD_0 + CCIE;

    /* TA0CCR0, Timer_A Capture/Compare Register 0 */
    TA0CCR0 = 3199;

    /* 
     * TA0CTL, Timer_A3 Control Register
     * 
     * TASSEL_0 -- TACLK
     * ID_0 -- Divider - /1
     * MC_1 -- Up Mode
     */
    TA0CTL = TASSEL_0 + ID_0 + MC_1;
}


src/grace/InterruptVectors_init.c
La interrupción despierta al MCU. El cuerpo del programa está en main().
/*
 *  ======== Timer0_A3 Interrupt Service Routine ======== 
 */
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR_HOOK(void)
{
    /* USER CODE START (section: TIMER0_A0_ISR_HOOK) */
 // Continua con el programa principal
 __bic_SR_register_on_exit(CPUOFF);
    /* USER CODE END (section: TIMER0_A0_ISR_HOOK) */
}



main.c
unsigned int contador = 0;
int dir=1;

/*
 *  ======== main ========
 */
int main(void)
{
    Grace_init();                   // Activate Grace-generated configuration
    
    while (1) {
  contador = contador + dir;
  if (contador==4){
   dir = -1;
  }

  if (contador == 1){
   dir = 1;
  }

  P1OUT = (1 << contador);

  LPM4;
    }
}



domingo, julio 14, 2013

Usar un 74HC165 con el MSP430 a través de USI

Conexión:
74HC165           MSP430
QH -------------> P1.7 (SDI)
CLK ------------> P1.5 (SCLK)
PL (o SH/LD) ---> P.1.2 (Cualquier pin vale).


InterruptVectors_init.c
/*
 *  ======== Timer0_A3 Interrupt Service Routine ======== 
 */
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR_HOOK(void)
{
    /* USER CODE START (section: TIMER0_A0_ISR_HOOK) */
    // Pedir al 74hc165 que lea las entradas
    P1OUT &= ~BIT2; // poner pin ld low
    P1OUT |= BIT2; // poner pin ld hight

    //Pedir al USI que lea 8 bits
    USICNT |= 8;

    /* USER CODE END (section: TIMER0_A0_ISR_HOOK) */
}


/*
 *  ======== USI Interrupt Service Routine ========
 */
#pragma vector=USI_VECTOR
__interrupt void USI_ISR_HOOK(void)
{
    /* USER CODE START (section: USI_ISR_HOOK) */
 USICTL1 &= ~USIIFG;
 clearDisplay();
 sendNumber(USISRL);
    /* USER CODE END (section: USI_ISR_HOOK) */
}

USI_init.c
/*
 *  This file is automatically generated and does not require a license
 */

#include <msp430.h>

/* USER CODE START (section: USI_init_c_prologue) */
/* User defined includes, defines, global variables and functions */
/* USER CODE END (section: USI_init_c_prologue) */

/*
 *  ======== USI_graceInit ========
 *  Initialize Universal Serial Interface
 */
void USI_graceInit(void)
{
    /* USER CODE START (section: USI_graceInit_prologue) */
    /* User initialization code */
    /* USER CODE END (section: USI_graceInit_prologue) */

    /* Disable USI */
    USICTL0 |= USISWRST;

    /* 
     * USI Control Register 0
     * 
     * USIPE7 -- USI function enabled
     * ~USIPE6 -- USI function disabled
     * USIPE5 -- USI function enabled
     * ~USILSB -- MSB first
     * USIMST -- Master mode
     * ~USIGE -- Output latch enable depends on shift clock
     * ~USIOE -- Output disabled
     * USISWRST -- USI logic held in reset state
     * 
     * Note: ~<BIT> indicates that <BIT> has value zero
     */
    USICTL0 = USIPE7 + USIPE5 + USIMST + USISWRST;

    /* 
     * USI Control Register 1
     * 
     * USICKPH -- Data is captured on the first SCLK edge and changed on the following edge
     * ~USII2C -- I2C mode disabled
     * ~USISTTIE -- Interrupt on START condition disabled
     * USIIE -- Interrupt enabled
     * ~USIAL -- No arbitration lost condition
     * ~USISTP -- No STOP condition received
     * ~USISTTIFG -- No START condition received. No interrupt pending
     * USIIFG -- Interrupt pending
     * 
     * Note: ~<BIT> indicates that <BIT> has value zero
     */
    USICTL1 = USICKPH + USIIE + USIIFG;

    /* 
     * USI Clock Control Register
     * 
     * USIDIV_0 -- Divide by 1
     * USISSEL_2 -- SMCLK
     * ~USICKPL -- Inactive state is low
     * ~USISWCLK -- Input clock is low
     * 
     * Note: ~<BIT> indicates that <BIT> has value zero
     */
    USICKCTL = USIDIV_0 + USISSEL_2;

    /* Enable USI */
    USICTL0 &= ~USISWRST;

    /* USER CODE START (section: USI_graceInit_epilogue) */
    /* User code */
    /* USER CODE END (section: USI_graceInit_epilogue) */
}

miércoles, julio 10, 2013

Usar un 74HC165 con el MSP430 y 8 interruptores

Nota:
LD --> PIN_PL
CLK--> PIN_CP
Q7 --> PIN_Q

74hc165.h

/*
 * 74hc165.h
 */

#ifndef FILE_74HC165_H_
#define FILE_74HC165_H_

#include "msp430.h"
#define PISO_IN_PORT P1IN
#define PISO_OUT_PORT P1OUT
#define PIN_PL BIT5
#define PIN_CP BIT4
#define PIN_Q BIT3

#define PIN_CP_HIGH PISO_OUT_PORT |= PIN_CP
#define PIN_CP_LOW PISO_OUT_PORT &= ~PIN_CP
#define PIN_PL_HIGH PISO_OUT_PORT |= PIN_PL
#define PIN_PL_LOW PISO_OUT_PORT &= ~PIN_PL

void init74hc165 (void);
unsigned char read74hc165(void);

#endif /* FILE_74HC165_H_ */

74hc165.c

/*
 * 74hc165.c
 */

#include "74hc165.h"

void pulseClock (void){
 PIN_CP_HIGH;
 PIN_CP_LOW;
}

void init74hc165 (void){
 PIN_PL_HIGH;
 PIN_CP_HIGH;
}

unsigned char read74hc165(void){

 unsigned char i;
 unsigned char ret = 0;
 volatile unsigned char readed;

 PIN_CP_HIGH;
 PIN_PL_LOW;
 PIN_CP_LOW;
 PIN_PL_HIGH;

 for (i=0; i < 8; i++){

  readed = PISO_IN_PORT;

  if ((readed & PIN_Q) == PIN_Q){
   ret = ret + (128 >> (i));
  }

  pulseClock();
 }

 return ret;
}