Arxiu de la categoria: Joan Quintana

script cncstroke: millorant la conversió DXF a G-Code, II

Creo un projecte amb LibreCAD, creo la capa ”stroke”, i aquí fiquem les polilínies, tal com s’ha explicat en l’anterior article [1], i tal com es mostra en la imatge. Amb llenguatge C++, el primer que fem és llegir el fitxer dxf i detectar la capa stroke, amb tots els seus punts. En el LibreCAD totes les línies són iguals, tenen un origen i un final. Però a mi m’interessa detectar les polilínies, que són les línies enllaçades de manera que el punt final d’una línia és el mateix que el punt d’origen de la línia següent. Recordem l’estructura de dades que es fa servr:

struct linia {
\tint x0;
\tint y0;
\tint x1;
\tint y1;
\tdouble length;
};

struct polilinia {
\tstd::vector vlinia;
\tdouble length;
};

std::vector vpolilinia;
Recorrem totes les línies, i anem afegint elements al vector polilínia, i dins de cada polilínia anem afegint elements al vector línia. Per cada línia i per cada polilínia, tenim calculada la seva longitud. Un cop tenim omplert el vector de polilínies amb les seves línies, ja podem recórrer totes les polilínies i generar la sortida G-Code, de manera que l’inici d’una polilínia està a profunditat -2mm, i el final de la polilínia està a profunditat 0mm, tal com s’aprecia en aquest tros del G-Code resultant, i en la imatge:

(* POLILINE #2 *)
G0 X 30 Y 30
G0 Z 3.000
F150
G1 Z -2.0
F400
G1 X 50 Y 40 Z -1.11
G1 X 60 Y 30 Z -0.55
G1 X 70 Y 40 Z 0
F150
G0 Z 5.000

Com s’aprecia en el G-Code, posicionem la broca al punt (30,30), foradem fins a -2.0mm, i anem passant per tres punts successius tot aixecant de forma proporcional la broca fins arribar al punt (70,40), en què la broca deixa d’atacar la superfície. Així s’aconsegueix un traç variable, tal com s’aprecia en la imatge. Amb aquesta tècnica podré perfilar detalls en els treballs CNC, com ara els cabells d’un retrat, o el traç en una caligrafia.

Com s’aprecia en la imatge (extrecta del projecte de fresar el retrat d’Albert Einstein en blanc i negre, en una altra entrada mostrarem el resultat final), es veu el resultat d’aplicar el script cncstroke per a les polilínies agrupades en la capa stroke del projecte LibreCAD. Veiem dos traços que acaben en punxa (a la part esquerra de la imatge, sobre fusta), i un altre traç, on no s’ha aplicat el script, que no acaba en punxa. A la part dreta de la imatge veiem un tros del projecte LibreCAD on s’han definit aquestes línies (dues que pertanyen a la capa cncstroke, i una altra que es fresa normal). Així doncs, amb un ús correcte del projecte LibreCAD, podem augmentar la resolució del fresat CNC, aconseguint un efecte més real i detallat.

Pots descarregar i estudiar el codi del script cncstroke des del següent enllaç [2] .
Referències:

Nota aclarativa: En el projecte cncstroke utilitzem el terme polilínia com a successió de línies enllaçades. Ara bé, per generar aquestes línies enllaçades, a LibreCAD, utilitzem l’eina línia (i no pas l’eina polilínia) (En una futura versió s’estudiarà la possibilitat d’utilitzar l’eina polilínia, o ambdues).

script cncstroke: millorant la conversió DXF a G-Code, I

Un dels treballs típics que es fan amb la CNC és el retrat de personatges en format blanc i negre. Per exemple, són coneguts els retrats del Che Guevara o l’Albert Einstein. Aquests dies estic treballant en la imatge de l’Ovidi Montllor [1].

La idea és senzilla i coneguda. Importo la imatge en LibreCAD [2] (el software CAD que utilitzo, que es open source), defineixo la silueta, i defineixo unes àrees de hatching que seran fresades (rebaixades). Faig servir el programa dxf2gcode [3] per exportar a G-Code, i freso tot el treball a una profunditat de 1.5mm. La limitació que tinc és que la fresa que faig servir és de 2mm de diàmetre, i això limita la resolució final que puc tenir.

Estic programant un petit script (cncstroke [4]) per tal de millorar la resolució dels meus treballs. Imaginem per exemple els cabells de l’Albert Einstein. Allò ideal és que les metxes de cabell acabin en punta, fent un traç que passi de gruixut a fi. Això s’aconsegueix fent que la profunditat d’atac de la broca sigui variable, des de 1.5mm de profunditat en l’inici del traç fins a 0mm al final del traç. Però per tal de què l’invent funcioni, no he de fer servir una broca normal, sinó una broca V-Shape (amb punta de 40 graus). D’aquesta manera aconseguiré l’efecte de fer un traç que passi de 2mm d’ample en l’origen a 0mm en l’extrem. Aquesta tècnica també serà molt útil per fresar lletres que simulin traços variables.

La idea és que en els meus projectes de LibreCAD tindré una capa amb la silueta bàsica (que fresaré amb una broca de 2mm), i una capa (que sempre anomenaré stroke) que constarà de polilínies que representaran el traç variable des de 2mm fins a 0 mm d’ample. Amb aquesta segona capa podré fer els detalls com ara cabells o caligrafia de lletres.

En aquest primer article només exposo l’estructura de dades que em permetrà gestionar la generació del G-Code a partir del projecte de LibreCAD. Quan recorri (programàticament) el contingut d’un projecte LibreCAD (format dxf), hauré de cercar la definició de la capa stroke i dels punts que conté. Això és relativament fàcil de fer. Aquesta successió de punts es poden agrupar en polilínies, entenent que una polilínia és un conjunt de línies que van empalmades.

Com que el número de poliínies és variable, i el número de línies que conté una polilínia també és variable, la millor manera de programar aquesta estructura amb llenguatge C++ és utilitzar vectors.

struct linia {
\tint x0;
\tint y0;
\tint x1;
\tint y1;
\tdouble dist;
};

struct polilinia {
\tstd::vector vlinia;
\tdouble dist;
};

std::vector vpolilinia;

Una línia consta d’un punt origen i un punt final (fàcilment es podrà calcular la longitud d’aquesta línia). Una polilínia consta d’un conjunt de línies, i la longitud de la polilínia serà la suma de les longituds individuals.

A continuació mostrem l’exemple mínim de com es poden gestionar diferents polilínies, cadascuna de les quals amb un número variable de línies.

// g++ -o polilinia polilinia.cpp
#include
#include
#include
#include
#include

struct linia {
\tint x0;
\tint y0;
\tint x1;
\tint y1;
\tdouble length;
};

struct polilinia {
\tstd::vector vlinia;
\tdouble length;
};

std::vector vpolilinia;

using namespace std;

int main() {
\t
\tdouble lengthlinia,lengthpolilinia;
\tpolilinia polilinia1;\t
\tlinia linia1;

\tlengthpolilinia=0;

\tlinia1.x0=34;
\tlinia1.y0=30;
\tlinia1.x1=120;
\tlinia1.y1=122;
\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));
\tlinia1.length=lengthlinia;
\tlengthpolilinia += lengthlinia;

\tpolilinia1.vlinia.push_back(linia1);

\tlinia1.x0=320;
\tlinia1.y0=322;
\tlinia1.x1=420;
\tlinia1.y1=422;
\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));
\tlinia1.length=lengthlinia;
\tlengthpolilinia += lengthlinia;

\tpolilinia1.vlinia.push_back(linia1);
\t
\tpolilinia1.length = lengthpolilinia;
\t
\tvpolilinia.push_back(polilinia1);
\t
\t//cout << vpolilinia.at(0).vlinia.size() << endl;

\t//anem per una altra polilinia
\tpolilinia1.vlinia.clear();
\tlengthpolilinia=0;

\tlinia1.x0=134;
\tlinia1.y0=130;
\tlinia1.x1=220;
\tlinia1.y1=222;
\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));
\tlinia1.length=lengthlinia;
\tlengthpolilinia += lengthlinia;

\tpolilinia1.vlinia.push_back(linia1);

\tlinia1.x0=220;
\tlinia1.y0=222;
\tlinia1.x1=320;
\tlinia1.y1=322;
\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));
\tlinia1.length=lengthlinia;
\tlengthpolilinia += lengthlinia;

\tpolilinia1.vlinia.push_back(linia1);

\tlinia1.x0=220;
\tlinia1.y0=222;
\tlinia1.x1=320;
\tlinia1.y1=322;
\tlengthlinia = sqrt(pow(linia1.x1-linia1.x0,2) + pow(linia1.y1-linia1.y0,2));
\tlinia1.length=lengthlinia;
\tlengthpolilinia += lengthlinia;

\tpolilinia1.vlinia.push_back(linia1);

\tpolilinia1.length = lengthpolilinia;

\tvpolilinia.push_back(polilinia1);\t

\t//cout << vpolilinia.at(1).vlinia.size() << endl;
\t//cout << vpolilinia.size() << endl;

\t//recorrem totes les polilínies
\tfor (int i=0; i
I la sortida per pantalla:

$ ./polilinia
polilinia #0. length: 267.358
linia #0. length: 125.936
linia #1. length: 141.421
polilinia #1. length: 408.779
linia #0. length: 125.936
linia #1. length: 141.421
linia #2. length: 141.421

En el següent article [5] s'explica la implementació del projecte cncstroke per tal de generar G-Code amb z-depth variable.

Referències:

Nota aclarativa: En el projecte cncstroke utilitzem el terme polilínia com a successió de línies enllaçades. Ara bé, per generar aquestes línies enllaçades, a LibreCAD, utilitzem l'eina línia (i no pas l'eina polilínia) (En una futura versió s'estudiarà la possibilitat d'utilitzar l'eina polilínia, o ambdues).

Prototip PCB de doble cara amb CNC

Aquests dies he estat perfeccionant com fer un prototipus de PCB amb la fresadora CNC.

Abans que res he hagut d’implementar el auto-probe per tal de compensar l’anivellament superficial de la placa on vull fresar. Aquest projecte requereix la màxima precisió. El tema del auto-probe va ser especialment ràpid i fàcil de fer, cosa rara doncs les coses fàcils normalment es compliquen de forma inesperada… Està documentat a [1].

Un cop l’auto-probe està funcionant, ja puc mirar de fer les plaques de doble cara. El principal repte està en girar la placa i que els forats en una capa i en l’altre coincideixin exactament. Com es veu a la foto, això s’ha aconseguit bastant bé, i la bona notícia és que hi ha marge per centrar bé els forats en la capa top (doncs en la foto es veu que els forats no estan exactament centrats). Tot està ben documentat en l’enllaç [2]

Ara que ja tinc el procés bastant clar, ja puc afrontar un petit projecte que requereix una placa de doble cara. Consisteix en muntar un mini-ordinador, amb finalitat purament acadèmica, amb un microprocessador Z80 [3]. Però abans de fer-lo, primer vindrà el programador de EEPROM [4], doncs a l’ordinador li hauré de carregar un programa en una EEPROM. No sé si tot plegat ho tindré enllestit abans de vacances.

En el passat havia fet plaques amb el mètode UV i amb el mètode de la planxa. Val a dir que sempre he tingut dificultats vàries en aconsegur plaques amb qualitat òptima. Ara, amb la CNC, estic buscant una manera ràpida de fer prototipus. En bona manera crec que ho he aconseguit. Ara bé, el procés, tot i que satisfactori, és més lent del que em pensava.

Joc del Simon. Extraescolar de Robòtica al Balmes

Ja hem acabat l’extraescolar de Robòtica al Balmes. Aquest any hem programat el joc del Simon amb una Raspberry Pi. Tota la documentació (i la programació didàctica) està a la wiki [1].

Durant aquestes 13 sessions hem anat treballant sobre diferents temes, que ens portaven a l’objectiu final de fer un prototipus de Simon:

  • Hem programat el script amb Python, viatjant per les diferents versions a mida que necessitàvem incorporar noves funcionalitats.
  • Hem connectat botons i LEDs als pins GPIO de la RPi.
  • Hem vist com, utilitzant transistors, podem disparar des dels pins GPIO senyals de 12V per encendre tires de LEDs blancs.
  • Hem discutit sobre l’alimentació de tot el sistema, i alternatives.
  • Hem discutit sobre com produir el so i la seva amplificació.
  • Hem dissenyat el moble final, utilitzant eines de fabricació digital com l’impressora 3D i la fresadora CNC.

Al final ha sigut un curs molt multidisciplinar, hem tocat moltes coses, tot i que per manca de temps, coneixements i d’infraestructura, moltes coses les ha implementat el professor i les ha mostrat a classe. Però al final l’experiència ha sigut enriquidora per tots.

El resultat final es pot veure a la foto i en aquest video:

Referències:

Amstrad PCW8256. Provant l’emulador Joyce



Aquests últims dies he reviscut l’ordinador Amstrad PCW8256 que teníem per casa els cap al 1986. El feia servir el meu pare per escriure, però també el féiem servir pels treballs de l’insti. Anava amb una pantalla monocroma verda, el teclat i la impressora d’agulles. Tota l’electrònica estava en el monitor, fins i tot la placa de l’impressora. I en el monitor també hi havia la disketera de 3”, que tenia dues cares.

He instal·lat el Joyce a la Raspberry Pi, i m’ha agradat molt reviure aquest sistema. Evidentment, s’ha d’escollir l’opció de lletres verdes, simulant la pantalla de fósfor verd.

L’ordinador venia amb dos disketes, que eren discs d’arrencada. El primer era el CP/M, el sistema operatiu, des del qual es podia accedir a l’intèrpret de Basic (Mallard Basic). El segon diskette, també bootable, era el Locoscript, que és el processador de textos amb què venia. He fet un document amb LocoScript sobre els rius de Catalunya, simulant com si fos un treball de l’insti.

També he jugat una estona al Tetris. L’emulador emula molt bé la màquina original. Si vols jugar al Tetris, has de fer eject del disket inserit (el CP/M)(el SO ja està carregat a la RAM), i ficar el disket del Tetris (Insert). Aleshores, ja des de la línia de comandes, ja es pot cridar a l’executable i jugar al Tetris, com es veu en la imatge.

Quins temps aquells! El link a la wiki:

Calibració del sensor de temperatura DS18B20

Ja tinc pràcticament enllestit el projecte IoT amb una REST Api [3][4] per llegir la temperatura d’un sensor DS18B20.

El problema (i greu) és que les temperatures que estic agafant del sensor són errònies. Per saber quina és la temperatura real en el meu barri (Gràcia-Barcelona) agafo com a referència la web de meteo.cat. L’estació meteorològica automàtica més propera és la de Zona Universitària, tot i que en realitat la temperatura no serà la mateixa ben bé. El carrer Joan Blanques, on tinc el sensor, és estret i enmig de la ciutat i el barri; la Zona Universitària és un espai més ample i obert, possiblement les temperatures mínimes tendeixen a ser més baixes…

Calibrar el sensor DS18B20 pot ser una tasca difícil. Aquí tenim un article [1] molt interessant sobre com procedir per la calibració. L’article és realment interessant, però no tinc el temps (ni les ganes) d’implementar-ho. El que sí que hauria d’haver fet, i això era fàcil, era adquirir 10 sensors DS18B20 (són baratos), descartar aquells que es desvien bastant de la temperatura real, i fer que les meves mostres siguin una mitjana dels altres sensors no-descartats, per exemple 5. Això no és cap problema, a la RPi tinc molts pins GPIO disponibles.

Una altra possibiltiat és utilitzar un altre sensor de temperatura. Per exemple, utilitizar el BMP280, que a més de la temperatura també tinc la pressió i la humitat relativa (i és barato). És molt interessant aquest article [2] on s’utilitza el BMP280 per construir una estació meteorològica alimentada per penell solar.

La conclusió és que confiar en què el sensor que tinc doni la temperatura correcta és un greu error. L’objectiu del projecte és fer un exemple didàctic de IoT, RestFul API, i gràfiques com a frontend. Això s’ha acomplert, ara només falta que la temperatura que llegeixo sigui real. Per tant, el que faré és mirar de fer una recta de regressió per aproximar-me a la temperatura real a partir de les dades que em dóna el meu sensor, suposant que la millor aproximació és una recta.

En la imatge es poden veure dues gràfiques. En la de dalt es veu la diferència entre la temperatura real i la del meu sensor. En la de baix es pot deduir la recta de regressió per convertir les dades del sensor a dades reals. De totes maneres, aquestes dades es corresponen a dos dies i mig. Esperaré una setmana més (i que pugin les temperatures del mes de maig, i així tenir més rang) per poder fer una recta de regressió.

Enllaços:

Internet of Things, Restful API amb Python i Flask, Raspberry Pi Zero i sensor de temperatura

Estic muntant un projecte acadèmic de Internet of Things. Es pretén mesurar la temperatura exterior del meu barri amb un sensor DS18B20 connectat a una Raspberry Pi Zero. Tal com es veu a la foto, he hagut de connectar un llapis Wifi USB. Idealment seria millor fer el projecte amb la nova Raspberry Pi Zero W que acaba de sortir fa un mes, i que porta wifi incorporat.

La temperatura es va gravant cada 10 minuts a una base de dades MongoDB. La part més interessant del projecte és programar una Restful API, i per fer-ho ho faré amb Python i el microframework Flask, a partir d’algun exemple que he trobat (veure els enllaços). En la versió 1 només hi havia un servei, que era bolcar totes les temperatures. La versió 2 ja fa més coses: bolcar totes les temperatures; recuperar la temperatura actual; filtrar per un dia; filtrar per varis dies al mateix temps.

Una altra part important és la capa de presentació, i per fer-ho utilitzo la llibreria Highcharts.com, que dóna uns resultats molt espectaculars. Per cada funció de la API es donarà un exemple html, per exemplificar com podem digerir les dades.

En les futures versions de la API es calcularan les mitjanes de temperatura diàries, mensuals i anuals, de manera que es puguin fer comparatives entre dies, mesos,… De moment encara no està disponible.

La API encara no és pública, estic en fase de desenvolupament. En el moment que sigui estable i pública ja ho anunciaré. De moment la tinc dins de casa, sota els efectes del termostat de la calefacció, amb la qual cosa els resultats no són interessants. Però la idea és després de Setmana Santa traslladar-ho tot al local, el sensor a l’exterior, i la Raspberry Pi dins del local. Es podrà accedir a la API en el domini http://joanqc.no-ip.biz/, però encara no està disponible.

La idea de desenvolupar aquesta API és, a part de què programar és divertit, poder utilitzar open data en format JSON a l’assignatura de Javascript (M06) en el cicle de Desenvolupament d’Aplicacions Web (DAW), a l’institut. Evidentment, hi ha molts exemples disponibles d’open data i format JSON. Però un exemple on els alumnes vegin d’on surten realment les dades, sempre serà interessant.

En el primer enllaç tenim la documentació i discussió de tota la posta a punt. És el punt de partida principal si es vol reproduir el projecte. En el segon enllaç es documenta la API, en les seves diferents versions.

Adaptació dels emuladors MAME i gngeo per limitar el temps de partida

Tenia pendent des de l’octubre aconseguir aquesta funcionalitat. Es tracta d’una màquina en que l’operació està controlada pel temps. Una moneda són 15 minuts de joc. Els emuladors MAME i gngeo (NeoGeo) tenen el botó de COIN que permet donar crèdits per jugar. Ara bé, el moneder controla el comptador de temps, i és necessari ficar monedes per donar temps a les partides. La comunicació entre el front-end i els dos emuladors es fa senzillament amb un fitxer de text on es llegeix i es grava el valor del comptador. La funcionalitat implementada és:

  • Quan estic en el front-end el temps no corre. Si es fica una moneda, suma el temps establert (15 minuts per defecte).
  • Quan entro a l’emulador (mame4all o gngeo), es llegeix el valor del temps restant, i comença a descomptar el temps, que està sempre visible.
  • Des de l’emulador puc ficar una moneda, suma el temps, i s’actualitza el comptador correctament.
  • Quan sortim de l’emulador i tornem al frontend, el temps queda ben guardat.
  • Si mentre jugo s’acaba el temps, es retorna al front-end, esperant la inserció d’una nova moneda.

Canvis en el codi i documentació:

    \t

  • http://wiki.joanillo.org/index.php/M%C3%A1quina_Arcade_amb_monedes_i_limitaci%C3%B3_de_temps._MAME_i_neogeo#Introducci.C3.B3_2

I el video:

retroplaneta.com

Big Arcade

Big Arcade

  • Màquines arcade i recreatives.
  • Construcció de recreatives. Personalitzem tamany i disseny
  • A part de màquines arcade i marcianitos, realitzem mobles on integrem arcade, pinball, jukebox.
  • Els nostres models inclouen: bartop, mini-bartop, màquina upright, arcade stick, cocktail. Visita tots els models a www.retroplaneta.com.
  • Visita el nostre local a Gràcia-Barcelona

www.retroplaneta.com

Màquina recreativa Big Arcade

Big Arcade

Big Arcade

Ja tinc acabada la nova màquina de peu , que anomenaré Big Arcade. El disseny ve directament d’un client que em va fer la petició (suposo que va trobar les mides per Internet), i realment m’agrada. En aquesta màquina s’ha cuidat uns quants detalls. Concretament, s’ha posat un moneder de Industrias Lorenzo, s’ha cuidat del so, una TV de 21 polzades, vidre protector, i s’ha millorat la col·locació i els acabats de la marquesina.

Quant al monitor, vaig aconseguir una TV de 21”, tot i que malauradament només té una resolució de 640x480px. Tot i que la resolució no és cap meravella, al final m’agrada aquests pixels una mica grossos, i és un consol saber que puc montar màquines amb aquesta resolució. En aquesta ocasió el cable HDMI to VGA no m’ha donat problemes, i això és un gran avanç doncs tinc una pista de per què en anteriors ocasions havia tingut tants problemes amb aquesta mena de cables.

Una altra millora que he fet en aquesta màquina és poder canviar el volum apretant dos botons, una solució totalment software, tant en el front-end com en els emuladors. Aquesta és una solució bona doncs ja no cal accedir al potenciòmetre de l’amplificador de so.

En definitiva, una nova màquina en què he implementat unes quantes millores en la construcció i en els acabats. Una màquina per disfrutar construint-la i jugant-la.

I el video: