¿Cómo subir un video usando Python?

El objetivo es publicar un video en la página http://www.youtube.com a través de un script escrito en Python. Esta vez toca hacerlo bajo la plataforma de Windows 8 con la versión 2.6 de Python.

Iniciamos descargando Python 2.6 Released: 01-Oct-2008 aquí

Windows x86 MSI Installer (2.6) (sig)

Después descargamos el proyecto de tokland@gmail.com, el cual se usa de la siguiente manera:

$ youtube-upload \
  --email=myemail@gmail.com --password=mypassword \
  --title="A.S. Mutter"--description="A.S. Mutter plays Beethoven"\
  --category=Music--keywords="mutter, beethoven" anne_sophie_mutter.flv
www.youtube.com/watch?v=pxzZ-fYjeYs

Parámetros

  • credenciales de la cuenta de youtube con la que subiremos el video: (email, password).
  • título, descripción, categoría y tags del video
  • ruta completa del video que deseamos publicar
  • si deseamos reemplazar un video existente, deberemos conservar la url y usarla como último parámetro:
    www.youtube.com/watch?v=pxzZ-fYjeYs

Dependencias

En el archivo readme de la sección Wiki del proyecto youtube-upload existe una descripción detallada de la instalación de las dependencias.

Nota: Antes de instalar los módulos, verificar que las variables de entorno PATH Y PYTHONPATH hayan sido agregadas.

variablesEntorno

Path=…;C:\Python26\

PYTHONPATH=C:\Python26\Lib;C:\Python26\DLLs;C:\Python26\Lib\lib-tk;

Una vez descargado el módulo gdata, lo descomprimimos y nos cambiamos a la carpeta, después escribimos python setup.py install.

Después descargamos el módulo pycurl desde esta liga, descomprimimos el contenido y lo copiamos a la siguiente ruta:C:\Python26\Lib\site-packages.

También es necesario instalar el módulo de progressbar, la última versión usa el módulo setuptools para su instalación, por lo que descargamos primero éste último.

Usamos el powershell de windows y escribimos lo siguiente (ver detalles)

> (Invoke-WebRequest https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py.Conten)t | python –

Después, descargamos el módulo de progressbar aquí y lo instalamos como los anteriores.

Una vez que tenemos todas las dependencias como se muestra en la siguiente imagen, podemos continuar.

site-packages

Al tratar de ejecutar el comando, aparece el siguiente error:

pycurl.error: (60, ‘SSL certificate problem, verify that the CA cert is OK

Lo solucionamos modificando el script youtube_upload.py como se describe aquí.

Así es como luce después de agregar el par de líneas

SSL_ERROR

 

Este es el comando para subir el video xilofono.mp4

python youtube_upload.py –email=correo@gmail.com –password=password –title=”test” –description=”anything” –category=Games –keywords=”upload, python” C:\Users\dregaladod\Videos\xilofono.mp4

Como resulta de la ejecución, el script regresa la url en la que fue publicada el video.

 

 

Marquesina con matriz de LEDs de 8×8

Introducción
IMG_20141123_151413

Lista de Materiales

1 Matriz ánodo/cátodo común de 8×8 rojo ($39.00)
1 Arduino nano v3 ($89.00)
13 Cables para proto macho-macho (40 cables x $39.00)
1 Registro de desplazamiento 74HC595 ($29.00)
1 Tira de 40 pines hembra ($3.00)
1 capacitor cerámico de 0.1 uF
2 protoboard mini ($21.00 x 2)

El costo total del proyecto es de $241.00, incluyendo el Arduino, los protoboard y los cables, si los restamos de la lista, el precio del proyecto se reduce a $71.00.

¿Cómo funciona la matriz de LEDs?
GMM-12088ASB
Esta es nuestra matriz de LEDs ánodo renglón,

matrix8x8

Inspiración

Diagrama de Fritzing

Código de Arduino

Empazamos haciendo un sketch de prueba para revisar que todos los leds de la matriz funcionen y que estamos direccionando correctamente las salidas.

1. Hacemos un barrido de izquierda a derecha y de abajo hacia arriba encendiendo los leds.
2. Hacemos el mismo barrido pero ahora apagándolos.

Este es el código para realizar la prueba
[cc lang=”c” width=”100%” lines=”-1″]
/*
* Example Code for an 8 x 8 LED Matrix
* For More Details Visit http://www.tinyurl.com/yhwxv6h
*
* Displays a test pattern lighting one LED after another
* To Play around with modifying the bitmap, un comment Example #2
*/

int speed = 5; //the delay time in milliseconds

int pauseDelay = 1; //the number of milliseconds to display each scanned line

//Pin Definitions
int rowA[] = {9,8,7,6,5,4,3,2}; //An Array defining which pin each row is attached to
//(rows are common anode (drive HIGH))
int colA[] = {17,16,15,14,13,12,11,10}; //An Array defining which pin each column is attached to
//(columns are common cathode (drive LOW))

//Pin connected to ST_CP of 74HC595
int latchPin = 10;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;
//The array used to hold a bitmap of the display
//(if you wish to do something other than scrolling marque change the data in this
//variable then display)
byte data[] = {0,0,0,0,0,0,0,0};

//Setup runs once when power is applied
void setup()
{
Serial.begin(9600); //Open the Serial port for debugging
for(int i = 0; i <8; i++){ //Set the 16 pins used to control the array as OUTPUTs
pinMode(rowA[i], OUTPUT);
// pinMode(colA[i], OUTPUT);
}
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}

//repeats
void loop()
{
//Example #1 – test pattern
//Run a small test program which lights up each light in time
test();

//Example #2 – static image
//Display a defined bitmap
/*
data[0] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
data[1] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
data[2] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
data[3] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
data[4] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
data[5] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
data[6] = B10101010; //row 1s bit mask (1 LED is on 0 LED is off)
data[7] = B01010101; //row 1s bit mask (1 LED is on 0 LED is off)
showSprite(speed);
*/
}

//An array to store power values to act as bit masks
const int powers[] = {1,2,4,8,16,32,64,128};

//Runs a pattern where each LED is lit one after another
void test(){
for(int i = 0; i < 8; i++){
for(int ii = 0; ii< 8; ii++){
data[i] = data[i]+ powers[ii]; //Goes through each row of lights lighting each column one after another
showSprite(speed);
}
}

for(int i = 0; i < 8; i++){
for(int ii = 0; ii< 8; ii++){
data[i] = data[i] – powers[ii]; //Goes through each row of lights turning off each column one after another
showSprite(speed);
}
}
}

void showSprite(int speed2){
for(int iii = 0; iii < speed2; iii++){ //show the current frame speed2 times
for(int column = 0; column < 8; column++){ //iterate through each column
for(int i = 0; i < 8; i++){
digitalWrite(rowA[i], HIGH); //turn off all row pins
}
for(int i = 0; i < 8; i++){ //Set only the one pin
if(i == column){ //digitalWrite(colA[i], LOW);
digitalWrite(latchPin, LOW);
int numberToDisplay = powers[i];
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);
digitalWrite(latchPin, HIGH);
} //turns the current row on
else
{
/* digitalWrite(latchPin, HIGH);
int numberToDisplay = powers[i];
shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay);
digitalWrite(latchPin, LOW); */
// digitalWrite(colA[i], HIGH);
}//turns the rest of the rows off
}

for(int row = 0; row > row) & 1;
if(bit == 1){
digitalWrite(rowA[row], LOW); //if the bit in the data array is set turn the LED on
}

}
delay(pauseDelay); //leave the column on for pauseDelay microseconds (too high a delay causes flicker)
}
}
}
[/cc]

Escritorio remoto en la Raspberry Pi

vnc_demo
Todos nos hemos conectado remotamente a un equipo, ya sea usando el programa de “Conexión a Escritorio Remoto” o la solución de TeamViewer gratuita. Ambos programas son un ejemplo de Virtual Network Computing (VNC), un sistema de escritorio compartido gráfico que usa el protocolo Remote Frame Buffer (RFB) para controlar de manera remota otra computadora.

¿Cuál es el punto?

El punto es que podemos tomar el control de la raspberry de forma gráfica instalando un servidor vnc.

Prerequisitos

Tener configurada una ip estática. ¿Cómo se hace?

¿Qué necesitamos instalar?

pi@raspberrypi ~ $sudo apt-get install tightvncserver

Una vez que la instalación termine, levantamos el servicio de la siguiente manera

pi@raspberrypi ~ $sudo vncserver

Nos solicitará un password para restringir el acceso remoto, lo tecleamos un par de veces y luego podemos rechazar la opción del segundo password.

Ahor necesitamos un cliente, instalamos una extensión del navegador chrome VNC Viewer for Google Chrome.

vnc_client

Ya está, ya podemos explorar el sistema operativo, mover archivos de configuración y hacer pruebas sin tener que conectar periféricos a la Raspberry Pi.

Si deseamos que esta opción este disponible cada vez que reiniciemos la Raspberry, tenemos que usar el siguiente script, lo podemos copiar y luego guardarlo como “tightvncserver”.

#!/bin/sh
# /etc/init.d/tightvncserver
# Thanks to Neil Black at www.neil-black.co.uk/raspberry-pi-beginners-guide
VNCUSER='pi'
case "$1" in
start)
su $VNCUSER -c '/usr/bin/tightvncserver :1'
echo "Starting TightVNC Server for $VNCUSER "
;;
stop)
pkill Xtightvnc
echo "TightVNC Server stopped"
;;
*)
echo "Usage: /etc/init.d/tightvncserver {start|stop}"
exit 1
;;
esac
exit 0

Después movemos el archivo “tightvncserver”, le damos permisos de ejecución y lo configuramos para que se ejecute al arranque

pi@raspberrypi ~ $ sudo cp tightvncserver /etc/init.d
pi@raspberrypi ~ $ sudo chmod a+x /etc/init.d/tightvncserver
pi@raspberrypi ~ $ sudo update-rc.d tightvncserver defaults

Nota: hacemos caso omiso de la advertencia “…missing LSB tags and overrides”

Para probar nuestro script, reiniciamos la raspberry

pi@raspberrypi ~ $ sudo shutdown -r now

Para deshabilitar el inicio automático del servidor vnc, escribimos la siguiente línea

pi@raspberrypi ~ $ sudo update-rc.d tightvncserver remove

Si quisieramos transferir archivos desde el cliente a la Raspberry Pi, podemos usar FileZilla y contectarnos por ssh (puerto 22), esta es la pantalla de configuración.
filezilla

¿Cómo usar control NES como dispositivo de entrada?

Introducción
20150517_155115
Para los que pertenecemos a la llamada generación de los millennials, ver un control NES nos transporta al época en que pasábamos tardes enteras jugando títulos como Mario Bros., Contra, Duck Hunt, Kung Fu, Baseball, etc. Ya sea que te haya tocado jugar con la consola de Nintendo o con versiones similares como family (famicom), la diversión estaba garantizada. Este fue mi juego favorito y ahora se puede jugar en este sitio http://www.8bbit.com/game.php?id=2732.

Claro que no es lo mismo jugar con el teclado que jugar con el control, la experiencia de usuario deja mucho que desear, las combinaciones de botones no son fáciles de hacer.

El proyecto de fin de semana

El objetivo es utilizar un viejo control NES como dispositivo de entrada. Con ayuda de la biblioteca NESpad.h (ver información del proyecto aquí) es muy sencillo realizar la interfaz del control usando un Arduino.

Inspiración

Materiales

  • 1 control NES (se puede conseguir en un tianguis por $15.00)
  • 1 Arduino
  • 5 Pines
  • Termofit (20 cm)
  • Material para soldar

Diagrama
20150517_155124

NES pin Arduino Pin
STROBE/LATCH Digital 2
CLOCK Digital 3
DATA Digital 4
+5V +5V
GND GND

configuración de colores/pines

Paso 1. Cortar el conector del control y soldar a cada cable un pin protegido por el termofit.

Paso 2. Realizar la conexión con el Arduino de acuerdo a el diagrama (ver documentación completa aquí).

Paso 3. Cargar el programa en el Arduino.


/*
this example from the NESpad Arduino library
displays the buttons on the joystick as bits
on the serial port - rahji@rahji.com

Version: 1.3 (11/12/2010) - got rid of shortcut constructor - seems to be broken

*/

#include

// put your own strobe/clock/data pin numbers here -- see the pinout in readme.txt
NESpad nintendo = NESpad(2,3,4);

byte state = 0;

void setup() {
Serial.begin(57600);
}

void loop() {

state = nintendo.buttons();

// shows the shifted bits from the joystick
// buttons are high (1) when up
// and low (0) when pressed
// Serial.println(~state, BIN);

//vamos a imprimir el o los botones seleccionados

if(state & NES_A)
Serial.println("NES_A");
if(state & NES_B)
Serial.println("NES_B");
if(state & NES_SELECT)
Serial.println("NES_SELECT");
if(state & NES_START)
Serial.println("NES_START");
if(state & NES_UP)
Serial.println("NES_UP");
if(state & NES_DOWN)
Serial.println("NES_DOWN");
if(state & NES_LEFT)
Serial.println("NES_LEFT");
if(state & NES_RIGHT)
Serial.println("NES_RIGHT");

delay(100);
}

Paso 4. Probar la comunicación con el monitor serial.

Paso 5. Probar el control con un juego real usando Processing.

Tomamos prestado el código del juego snake del sitio de openprocessing.org escritor por Anson Liang.

Modificamos el código para incluir la comunicación serial y replicar la funcionalidad del evento keypress.

/* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/27164*@* */
/* !do not delete the line above, required for linking your tweak if you upload again */

// Snakes
// By: Anson Liang
// This is a classic snake game, just made it for fun.
//
import processing.serial.*;
color col=color(255,255,192);
color foodColor = color(255,0, 0);
float speed = 100;
int cx, cy;

int moveX = 0;
int moveY = 0;
int snakeX = 0;
int snakeY = 0;
int foodX = -1;
int foodY = -1;
boolean check = true;
int []snakesX;
int []snakesY;
int snakeSize = 1;
int windowSize = 200;
boolean gameOver = false;
PFont Font = createFont("Arial",20, true);
String buff = "";
boolean pausado = false;
boolean firstTime = true;
Serial port;
void setup(){
size(int(windowSize), int(windowSize),P3D);

background(0);
speed = 100;
speed=speed/frameRate;
snakesX = new int[100];
snakesY = new int[100];

cx = width/2;
cy = height/2;

snakeX = cx-5;
snakeY = cy-5;
foodX = -1;
foodY = -1;
gameOver = false;
check = true;
snakeSize =1;
// Uses the first available port
port = new Serial(this, Serial.list()[7], 57600);
//print(Serial.list()[7]); ///dev/tty.usbserial-A9007KC7
}

void draw(){

while (port.available() > 0) {
//print("listening");
serialEvent(port.read());
}

if(!pausado && speed%10 == 0){

background(0);
runGame();
firstTime = true;
}else if(firstTime && pausado){
String modelString = "pause";
textAlign (CENTER);
textFont(Font);
text(modelString,100,100,40);
firstTime = false;
}

speed++;
}

void serialEvent(int serial) {

if(serial != '\n')
{
buff += char(serial);
}else if(buff.length()> 0)
{
//quitamos el caracter de retorno de carro!!
buff = buff.substring(0,buff.length()-1);

if(buff.equals("NES_UP") == true) { if(snakesY[1] != snakesY[0]-10){moveY = -10; moveX = 0;}}
if(buff.equals("NES_DOWN") == true) { if(snakesY[1] != snakesY[0]+10){moveY = 10; moveX = 0;}}
if(buff.equals("NES_LEFT") == true) { if(snakesX[1] != snakesX[0]-10){moveX = -10; moveY = 0;}}
if(buff.equals("NES_RIGHT") == true) { if(snakesX[1] != snakesX[0]+10){moveX = 10; moveY = 0;}}
if(buff.equals("NES_START") == true) {
if(!gameOver){
pausado = !pausado;
}
else{
reset();
}
}
//limpiamos el buffer
buff = "";

}
}

void reset(){
snakeX = cx-5;
snakeY = cy-5;
gameOver = false;
check = true;
snakeSize =1;
moveY = 0;
moveX = 0;
}
void runGame(){

if(gameOver== false){
drawfood();
drawSnake();
snakeMove();
ateFood();
checkHitSelf();

}else{
String modelString = "game over";
textAlign (CENTER);
textFont(Font);
text(modelString,100,100,40);
}
}
void checkHitSelf(){
for(int i = 1; i < snakeSize; i++){
if(snakeX == snakesX[i] && snakeY== snakesY[i]){
gameOver = true;
}
}
}
void ateFood(){
if(foodX == snakeX && foodY == snakeY){
check = true;
snakeSize++;
}
}
void drawfood(){
fill(foodColor);
while(check){
int x = (int)random(1,windowSize/10);
int y = (int)random(1,windowSize/10);
foodX = 5+x*10;
foodY = 5+y*10;

for(int i = 0; i < snakeSize; i++){
if(x == snakesX[i] && y == snakesY[i]){
check = true;
i = snakeSize;
}else{
check = false;
}
}

}

rect(foodX-5, foodY-5, 10, 10);

}
void drawSnake(){
fill(col);

for(int i = 0; i 0; i--){
snakesX[i] = snakesX[i-1];
snakesY[i] = snakesY[i-1];
}
}

void snakeMove(){
snakeX += moveX;
snakeY += moveY;
if(snakeX > windowSize-5 || snakeX windowSize-5||snakeY < 5){
gameOver = true;
}
snakesX[0] = snakeX;
snakesY[0] = snakeY;

}

void keyPressed() {
if(keyCode == UP) { if(snakesY[1] != snakesY[0]-10){moveY = -10; moveX = 0;}}
if(keyCode == DOWN) { if(snakesY[1] != snakesY[0]+10){moveY = 10; moveX = 0;}}
if(keyCode == LEFT) { if(snakesX[1] != snakesX[0]-10){moveX = -10; moveY = 0;}}
if(keyCode == RIGHT) { if(snakesX[1] != snakesX[0]+10){moveX = 10; moveY = 0;}}
if(keyCode == 'R') {reset();}
}

Cambia tu aburrido mouse por este joystick sacado de la basura

Hoy encontré un stick de un viejo control de playstation 1, que hace tiempo había rescatado de la basura con la esperanza de reutilizarlo alguna vez. Así que sin pensarlo dos veces me dí a la tarea de soldar unos pines a los potenciometros, conectar algunos cables, escribir algo de código para mi Arduino Duemilanove y reciclar código de un sketch de Processing.

El funcionamiento del joystick es sencillo, son dos potenciometros de los que se leen los valores x y y; sólo hay conectarlos a las entradas análogas del Arduino y enviar los valores a la computadora.

joystick_arduino

 

Este es el sketch para el Arduino

int ledPin = 13;
int joyPin1 = 0; // variable x conectado al pin análogo 0
int joyPin2 = 1; // variable y conectado al pin análogo 1
int value1 = 0; // valor digitalizado del pin 0
int value2 = 0; // valor digitalizado del pin 1
void setup() {
beginSerial(9600);
}
//convierte un numero a su valor ascii
int tochar(int data) {
return (data + 48);
}
void loop() {
// lee los valores de los potenciometros
value1 = analogRead(joyPin1);
//pequeña pausa entre las lecturas
delay(100);
//lee el segundo potenciometro
value2 = analogRead(joyPin2);

//envia el valor de x
serialWrite(‘X’);
//envia el valor numerico digito por digito, solo 8 bits a la vez
if(value1>0){
while(value1){
serialWrite(treatValue(value1%10));
value1 = value1/10;
}
}else serialWrite(‘0’);
serialWrite(10);
//envia el valor de y
serialWrite(‘Y’);
if (value2>0){
while(value2){
serialWrite(treatValue(value2%10));
value2 = value2/10;
}
}else serialWrite(‘0’);
serialWrite(10); //el fin de linea marca el final de la lectura
}

Pantallazo-joystick_storingInput

y este el sketch de Processing
[cc lang=”java” tab_size=”2” lines=”100”]

// Joystick
// por Dennys Regalado Díaz
//
// Creado el 11 de septiembre de 2009
////////////
int num = 60;
float mx[] = new float[num];
float my[] = new float[num];

import processing.serial.*;

String buff = “”;
int x_val=0,y_val=0;
int NEWLINE = 10;

Serial port;

void setup(){
size(400,400);
smooth();
noStroke();
fill(255, 153);
// Print a list in case COM1 doesn’t work out
println(“Available serial ports:”);
println(Serial.list());

//port = new Serial(this, “COM1”, 9600);
// Uses the first available port
port = new Serial(this, Serial.list()[0], 9600);
}

void draw()
{
background(41);
while (port.available() > 0) {
serialEvent(port.read());
}

// Reads throught the entire array
// and shifts the values to the left
for(int i=1; i<num; i++) {
mx[i-1] = mx[i];
my[i-1] = my[i];
}

int xx = (int) map(constrain(x_val,10,1024),0,1024,10,width-10);
int yy = (int) map(constrain(y_val,10,1024),0,1024,10,height-10);
mx[num-1] = xx;
my[num-1] = yy;
float r = random(125,205);
float g = random(100,205);
float b = random(150,200);

for(int i=0; i<num; i++) { fill(r,g,b,153); ellipse(mx[i], my[i], i/2, i/2); } println(“x:”+xx+”, y:” + yy); } void serialEvent(int serial) { if(serial != NEWLINE) { buff += char(serial); } else if(buff.length()> 0) {
char c = buff.charAt(0);
buff = buff.substring(1);
if (c == ‘X’)
x_val = Integer.parseInt(buff);
else if (c == ‘Y’)
y_val = Integer.parseInt(buff);
buff = “”;
}
}
[/cc]

Visualización de datos en 15 minutos con Tableau

Este post es sobre una de la áreas que he estado explorando recientemente, la visualización de datos. Les recomiendo descargar la versión pública de Tableau y comenzar a jugar con la herramienta, está pensada para usuarios sin ningún tipo de background de programación, de hecho la intención es facilitar la exploración de datos y poder contar una historia de forma visual.

No es necesario conectarse a una base de datos para explotar un conjunto de datos, podemos usar como fuente un archivo de texto separado por comas (.csv), separado por tabuladores (.tab o .tsv) o un archivo plano (.txt).

Voy a describir el proceso para generar una visualización que muestra el porcentaje de la población que habla una lengua indígena en el estado de Oaxaca de acuerdo al censo 2010 del INEGI.

1. Descargar la fuente del INEGI. Estas son las instrucciones para consultar la información del inegi, una vez que obtengamos la vista que necesitamos, nos vamos al final de la página y elegimos formato “.csv” y luego el botón exportar.

consulta interactiva de los resultados del censo de población y vivienda 2010 en la siguiente liga: http://bit.ly/q1d7tl, active las casillas de Entidad y municipio y Habla indígena y lengua, presione el botón de Ver consulta, presione el signo de + Habla lengua indígena y de igual manera el signo de + de la entidad de su interés para que se desagregue la información.

 

2. Ya tenemos la fuente, ahora abrimos Tableu, en la sección de Connect in a file, elegimos “Text file”, buscamos nuestra fuente de datos y la cargamos.

3. A continuación veremos dos secciones del lado izquierdo, “Dimensions” y “Measures”, tomamos de las dimensiones y métricas que deseamos visualizar arrastrándolas a cualquiera de las regiones: Color, Size, Label, Detail o Tooltip.

marksTableau

 

4. Seleccionamos una de las plantillas que tenemos disponibles, algunas se mostrarán deshabilitadas hasta el set de datos cumpla con ciertas características como un número mínimo de dimensiones y métricas.

showmeTableau

 

5. La visualización esta lista para compartir, para realizar la publicación debemos registrarnos en el sitio con anterioridad.Sheet 5

Voy a continuar explorando otras herramientas con raw y plot.ly y publicar sobre ellas.

Cámara de vigilancia con Raspberry Pi y una webcam

La necesidad de tener una cámara de vigilancia para el cuarto de los bebés es muy común hoy en día. Así que decidí realizar una por mí mismo usando una Raspberry, una vieja webcam y este tutorial de Makezine.

Objetivo

La cámara debe:

  • ser fácil de usar de forma remota a través de una página web
  • mostrar imágenes a color de alta resolución
  • permitir rotar la cámara de izquierda a derecha y de arriba hacia abajo, ya sea con arrastrando el dedo sobre dispositivos touch o con las flechas del teclado.

Lista de Materiales

  • una webcam ($500.00)
  • raspberry pi + SD card 4G + fuente de alimentación ($1,000)
  • impresión del case ($250)
  • 2 servomotores pequeños ($90 x 2 = $180)
  • 1 cable USB reciclado
  • 1 cincho sujeta cables

El costo total del proyecto es de aproximadamente de $2,000, el costo más grande es sin duda la raspberry, si no incluimos el costo de la webcam, el costo se puede reducir a $1,500.

imageimage

imageimage

imageimage

Problemas

Estos son los modelos en 3D de la carcasa de la cámara, listos para ser impresos. En las dos imágenes de arriba se muestran los dos “brazos” que embonan con los dos servo motores. Sobre el de la izquierda se monta la cámara y permite girar hacia arriba y hacia abajo. El brazo de la derecha va montado sobre la caja que protege a la Raspberry Pi,  y permite mover la cámara de izquierda a derecha.

El detalle es que los orificios sobre los cuales embonaran los servo motores, no cuentan con dientes que encajen con la cabeza de los motores. Esto causa que la cabeza del servo gire pero los brazos no lo hagan con la misma fuerza y respuesta que se espera. También provoca que con el peso de la cámara el brazo inferior se tambaleé y terminé por caerse.

Mejoras

Hardware

Para solucionar el problema anterior, decidí usar los accesorios originales de los servo motores y pegarlos a los brazos de la cámara. Con esto mejoró notablemente la respuesta de los servo motores, pero continuó teniendo problemas con el peso de la cámara. Después de realizar una serie de movimientos de izquierda a derecha, el peso de la cámara la hace caer.

Software

El código original de Matt Stultz sólo incluye la respuesta a los eventos del teclado, usando la biblioteca de jquery mobile agregamos los eventos touch para controlar los servo motores. Pronto subiré las modificaciones del proyecto a un repositorio de GitHub.

Posibles mejoras

Se encuentra pendiente publicar la IP de la raspberry para que se puede tener acceso a la cámara desde Internet.

¿Cómo usar la comunicación serial en un ATtiny85 programado desde Arduino?

Lo primero que hay que hacer es conocer los pines de nuestro microcontrolador. Para eso consultamos el archivo pins_arduino.h que corresponde al core que estamos utilizando.

pines

Después es necesario agregar un bloque de configuración con el nombre “ATtiny85 8 Mhz clock (w / Arduino as ISP)”, en el archivo boards.txt.

append_8mhz_attiny85_entry

attiny85-8arduinoisp.name=ATtiny85 8 MHz clock (w/ Arduino as ISP)
attiny85-8arduinoisp.upload.using=arduino:arduinoisp
attiny85-8arduinoisp.upload.maximum_size=8192
attiny85-8arduinoisp.build.mcu=attiny85
attiny85-8arduinoisp.build.f_cpu=8000000L
attiny85-8arduinoisp.build.core=attiny45_85

Resulta que la biblioteca de SoftwareSerial que incluye el arduino 1.0.5 no funciona para nuestros fines, por lo que hay que descargar la versión más reciente en la siguiente liga.

Ver más información sobre esta biblioteca aquí.

Agregamos la biblioteca desde nuestro IDE: Sketch > Importar Librería > Add Library…, elegimos el .zip que acabamos de descargar (NewSoftSerial10c.zip) y listo.

addLibrary

Usamos el siguiente ejemplo:

/*
Takes an input on the AtTiny85 from the VERY TRICKY analogue input pin 2 (as labeled in HLT tutorial)

and outputs these with Software serial to the arduino uno, or Duemillanove

Hookup
ATTINY85 pin 3 -> Arduino Uno pin 0
ATTINY85 pin 4 -> Arduino Uno pin 1

*/

#include
// Definitions
#define rxPin 3
#define txPin 4

//SoftwareSerial mySerial(rxPin, txPin);
NewSoftSerial mySerial(rxPin, txPin);

int sensorPin = 1; //7 PB2 Ain1
int sensorVal = -1;

boolean switchFans = 0;

// the setup routine runs once when you press reset:
void setup() {
pinMode(sensorPin, INPUT);
mySerial.begin(9600);
}

// the loop routine runs over and over asensorpingain forever:
void loop() {

sensorVal = analogRead(sensorPin);
mySerial.print("Input Val: ");
mySerial.print(sensorVal);
mySerial.println();
}

Al intentar compilar se generan los siguientes errores:

C:\Program Files (x86)\arduino-0019\libraries\NewSoftSerial\NewSoftSerial.cpp: In static member function 'static void NewSoftSerial::enable_timer0(bool)':
C:\Program Files (x86)\arduino-0019\libraries\NewSoftSerial\NewSoftSerial.cpp:520: error: 'TIMSK0' was not declared in this scope
C:\Program Files (x86)\arduino-0019\libraries\NewSoftSerial\NewSoftSerial.cpp:526: error: 'TIMSK0' was not declared in this scope

Por lo que es necesario modificar el archivo fuente NewSoftSerial.cpp en las líneas 517 y 523, como se muestra en la figura.

NewSoftwareSerial_changesMás información aquí.

Al descargar el programa no olviden seleccionar como tarjeta ATtiny85 8 Mhz clock (w / Arduino as ISP) y como programador Arduino as ISP.

Para verificar la comunicación serial utilizaremos el arduino para recibir los mensajes que envía el ATtiny y posteriormento los visualizaremos desde el IDE empleando el Monitor Serial del menú de Herramientas.

Cargamos un sketch mínimo como este a nuestro Arduino, el cual nos servirá de monitor.

It just looks like this
///////
void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:
 
}

//////

Después cargamos el programa, sin olvidar reajustar los parámetros Tarjeta (en mi caso Arduino Duemilanove w/ATmega168)  y Programador (AVRISP mkJI) en nuestro IDE.

Posteriormente, hacemos las siguientes conexiones:

ATTINY85 pin 3 -> Arduino Uno pin 0
ATTINY85 pin 4 -> Arduino Uno pin 1

En el pin 7 de nuestro ATtiny conectamos alguna señal analógica que podamos variar, en este ejemplo usé un potenciometro alimentado del mismo Arduino con +5V.

Ejemplo de conexión con el Arduino

Después simplemente abrimos el Monitor Serial desde el sketch que acabamos de cargar y giramos el potenciometro para visualizar diferentes valores.

serialMonitor

Ver guía completa aquí.

 

¿cómo portar tu proyecto Arduino a un microcontrolador de bajo costo?

En este post se describe, por medio de pantallazos, la forma en que se debe configurar un Arduino (Windows 7) para usarlo como programador de un ATtiny85.

Esta opción nos brinda una forma sencilla de portar nuestros proyectos a un microcontrolador de bajo costo ($60 pesos).

 

pasos1_y_2

paso3 paso4 paso5y6

Fuente: Programming an ATtiny w/ Arduino 1.0

Para poder usar la biblioteca SoftwareSerial son necesarios unos pasos extras:

Es necesario cambiar  a 8Mhz para utilizar SoftwareSerial

Es necesario cambiar a 8Mhz para utilizar SoftwareSerial

  1. Seleccionar Tarjeta > ATtiny85 (internal 8 MHz clock) en el menú de Herramientas.
  2. Elegir la opción “Grabar Secuencia de Inicio” del menú Herramientas.

Nota: Si no aparece la opción “ATtiny85 (internal 8 MHz clock)”, agregar el siguiente bloque al final del archivo “boards.txt”, reiniciar el IDE de Arduino y verificar nuevamente.

attiny85-8.name=ATtiny85 (internal 8 MHz clock)
attiny85-8.bootloader.low_fuses=0xe2
attiny85-8.bootloader.high_fuses=0xdf
attiny85-8.bootloader.extended_fuses=0xff
attiny85-8.upload.maximum_size=8192
attiny85-8.build.mcu=attiny85
attiny85-8.build.f_cpu=8000000L
attiny85-8.build.core=arduino:arduino
attiny85-8.build.variant=tiny8

Para más información consultar la siguiente liga.

Hint: Comparar los archivos boards.txt con la versión de este repositorio.

Abrir cerradura eléctrica desde mi Android

En el departamento donde vivo está instalado un interphone de voz, con varios años de antigüedad, pero que sigue funcionando. Funciona para comunicarse por voz y para activar la cerradura de la entrada al edifico.

Esta es la cerradura, la fuente de alimentación y el arreglo de timbres, uno por departamento.

chapa_electricareguladortimbres_entrada

El circuito receptor se alimenta de 16v DC, una fuente común para todos los departamentos del edificio. El botón de pulso, tiene la finalidad de cerrar momentáneamente el circuito de la cerradura eléctrica y abrir la puerta del edificio.

La solución consiste en conectar un relevador, controlado por un arduino, al circuito del receptor. Luego comunicar el arduino con el android vía bluetooh, para controlar el botón que abre la puerta desde la interfaz del teléfono.

Este es el circuito del receptor que se encuentra en la cocina.

interphone

Este es el circuito que funcionará como interruptor a distancia, en la parte inferior se encuentra la antena bluetooth, sobre el protoboard está montado el circuito del relevador y todos los cables van al arduino que se encuentra en la parte posterior del protoboard.

artefacto

Lista de materiales

1 arduino duemilanove
1 relevador 5V DC RAS-0510 ($5.00)
1 módulo bluetooth JY-MCU ($240.00)
1 transistor PN 2222A
1 diodo rectificador

materiales

Dudas sobre cómo funciona un relevador

Cómo realizar la configuración inicial del módulo de bluetooth JY-MCU con Arduino

Este es el diagrama de conexiones para hacer funcionar el relevador.

Aplicación de Android para comunicarse por bluetooth con el Arduino

El cliente bluetooth para el smartphone es muy fácil de realizar usando el MIT App Inventor, una plataforma para prototipar sin escribir una sola línea de código, basado en Scratch, un lenguaje que se usa para enseñar a los niños a programar, ¿genial no?

Después de literalmente unir las piezas del rompecabezas, exportamos nuestra aplicación (.apk) usando el WiFi, lógicamente la computadora en donde tienen el sketch y el smartphone deben compartir el mismo punto de acceso.

Y eso es todo, ahora no necesito la llave del portón para entrar al edificio, es más rápido  abrir la app y dar un tap a la pantalla.