‘coding’ Category

DoMina – la domotica in salsa mia

aprile 26th, 2013

Ho una scheda Arduino, uno shield ethernet per Arduino e una scheda con 4 relè compatibile con Arduino.

Facile! Comando i relè dal web.

E’ la prima parte di un progetto più ampio che forse non porterò mai a termine, e quindi non va ne parlerò. Comunque volevo avere i relè pilotabili da una pagina web quindi, in un contesto più ampio, si potrebbe anche parlare di domotica. L’ho chiamato DoMina da DOmotica e dj MINAccia, il mio alter-ego musicale.

Lo scheda che ho fatto è questo:

Schema di principio

Schema di principio

E’ molto semplice: a sinistra c’è una fotoresistenza (per misurare l’intensità della luce) e una LM35 (per misurare la temperatura). A destra ci sono i 4 relè e 4 pulsanti. I pulsanti li ho implementato nel caso qualcuno con un cellulare del medioevo non riesco ad accedere alla paginetta web di controllo ma che comunque abbia il desiderio di attivarne qualcuno.

Foto del primo prototipo

Foto del primo prototipo

Per essere più professionale poi mi sono fatto anche lo stampato per essere usato come shield autoprodotto per Arduino:

Circuito stampato

Circuito stampato

Nello stampato ho aggiunto un pulsante in più non presente nello schema precedente. Col pulsante, i contatti sono quei due in basso a sinistra, servono per il reset di Arduino perchè non chiedetemene il motivo, quando dai corrente ad Arduino non carica la parte relativa alla rete, dopo un reset riparte tutto. Non so se dipende dal fatto che sia il mio Arduino che l’Ethernet Shield siano vecchi e danno problemi con le librerie aggiornate, comunque ho risolto così :)

Ed ecco tutto l’ambaradan montato e funzionante:

Tutto montato e funzionante

Tutto montato e funzionante

Una volta collegato alla rete si può accedere all’apposita pagina web per accendere o spegnere i relè e controllare i valori dei sensori. E’ compatibile con qualsiasi device dotato di browser, in questo caso un Kindle

Pagina di controllo su Kindle

Pagina di controllo su Kindle

Il codice è un mischione di vari parti di codice copiati qua e la o scritti da me in passato, adesso non mi ricordo esattamente tutte le provenienze ma parecchio viene dagli sketch di esempio di Arduino (in particolare per la parte web).

Ecco il codice:

#include <SPI.h>
#include <Ethernet.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192,168,200,5);
EthernetServer server(80);
String readString;

int releA = 6;
int statoA = 0;
int releB = 7;
int statoB = 0;
int releC = 8;
int statoC = 0;
int releD = 9;
int statoD = 0;
int pinT = 0;
int pinL = 1;
float tempc = 0;
int lux = 0;
int sample[8];
int i;
int valA = 0;
int switchA = 2;
int valB = 0;
int switchB = 3;
int valC = 0;
int switchC = 4;
int valD = 0;
int switchD = 5;

void setup(){
Serial.begin(9600);
Ethernet.begin(mac, ip);
pinMode(releA, OUTPUT);
digitalWrite(releA, HIGH);
pinMode(releB, OUTPUT);
digitalWrite(releB, HIGH);
pinMode(releC, OUTPUT);
digitalWrite(releC, HIGH);
pinMode(releD, OUTPUT);
digitalWrite(releD, HIGH);
pinMode(switchA, INPUT);
pinMode(switchB, INPUT);
pinMode(switchC, INPUT);
pinMode(switchD, INPUT);
}

void loop(){
valA = digitalRead(switchA);
if (valA == HIGH){
if(statoA == 0){
digitalWrite(releA, LOW);
statoA = 1;
delay(200);
}else if(statoA == 1){
digitalWrite(releA, HIGH);
statoA = 0;
delay(200);
}
}
valB = digitalRead(switchB);
if (valB == HIGH){
if(statoB == 0){
digitalWrite(releB, LOW);
statoB = 1;
delay(200);
}else if(statoB == 1){
digitalWrite(releB, HIGH);
statoB = 0;
delay(200);
}
}
valC = digitalRead(switchC);
if (valC == HIGH){
if(statoC == 0){
digitalWrite(releC, LOW);
statoC = 1;
delay(200);
}else if(statoC == 1){
digitalWrite(releC, HIGH);
statoC = 0;
delay(200);
}
}
valD = digitalRead(switchD);
if (valD == HIGH){
if(statoD == 0){
digitalWrite(releD, LOW);
statoD = 1;
delay(200);
}else if(statoD == 1){
digitalWrite(releD, HIGH);
statoD = 0;
delay(200);
}
}

EthernetClient client = server.available();
if (client) {
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
readString.concat(c);

if (c == ‘\n’ & currentLineIsBlank) {
Serial.print(readString);
client.println(“HTTP/1.1 200 OK”);
client.println(“Content-Type: text/html”);
client.println(“Connection: close”);
client.println();
client.println(“<!DOCTYPE HTML>”);
client.println(“<html>”);
client.println(“<head><title>DoMina</title>”);
client.println(“<meta charset=utf-8>”);

// A
if(readString.indexOf(“A=1″) > 0){
digitalWrite(releA, LOW);
Serial.println(“acceso”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoA = 1;
break;
}else
if(readString.indexOf(“A=0″) > 0){
digitalWrite(releA, HIGH);
Serial.println(“spento”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoA = 0;
break;
}

//B
if(readString.indexOf(“B=1″) > 0){
digitalWrite(releB, LOW);
Serial.println(“acceso”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoB = 1;
break;
}else
if(readString.indexOf(“B=0″) > 0){
digitalWrite(releB, HIGH);
Serial.println(“spento”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoB = 0;
break;
}

//C
if(readString.indexOf(“C=1″) > 0){
digitalWrite(releC, LOW);
Serial.println(“acceso”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoC = 1;
break;
}else
if(readString.indexOf(“C=0″) > 0){
digitalWrite(releC, HIGH);
Serial.println(“spento”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoC = 0;
break;
}

//D
if(readString.indexOf(“D=1″) > 0){
digitalWrite(releD, LOW);
Serial.println(“acceso”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoD = 1;
break;
}else
if(readString.indexOf(“D=0″) > 0){
digitalWrite(releD, HIGH);
Serial.println(“spento”);
client.println(“<meta http-equiv=\”refresh\” content=\”0; url=http://192.168.200.5 \”/>”);
statoD = 0;
break;
}

client.println(“</head><body><div style=’font-family: arial; font-size: 2em; line-height: 2em; border: 5px solid #000; margin: 5px; padding: 5px;’>”);

client.println(“Temperatura: “);
for(i = 0; i < 7; i++){
sample[i] = (float)( 5.0 * analogRead(pinT) * 100.0) / 1024.0;
tempc = tempc + sample[i];
}

client.print(tempc/8.00);
tempc=0;
client.print(“°”);

client.println(“<br />”);
lux=analogRead(pinL);
client.println(“Luce: “);
client.println(“<span style=’background-color: #0ee;’>”);
client.println(lux);
for(i=0; i<((lux)/100); i++){
client.println(“&nbsp;”);
}
client.println(“</span>”);
lux=0;

//A
client.println(“<br /><b>Relè A: </b>”);
if(statoA == 0){
client.println(“<span style=’color:grey; font-weight:bold;’>OFF</span> – “);
client.println(“<a href=\”?A=1\”>Accendi</a> | “);
}else if(statoA ==1){
client.println(“<span style=’color:green; font-weight:bold;’>ON</span> – “);
client.println(“Accendi | “);
}
if(statoA == 0){
client.println(“Spegni”);
}else if(statoA ==1){
client.println(“<a href=\”?A=0\”>Spegni</a>”);
}

//B
client.println(“<br /><b>Relè B: </b>”);
if(statoB == 0){
client.println(“<span style=’color:grey; font-weight:bold;’>OFF</span> – “);
client.println(“<a href=\”?B=1\”>Accendi</a> | “);
}else if(statoB ==1){
client.println(“<span style=’color:green; font-weight:bold;’>ON</span> – “);
client.println(“Accendi | “);
}
if(statoB == 0){
client.println(“Spegni”);
}else if(statoB ==1){
client.println(“<a href=\”?B=0\”>Spegni</a>”);
}

//C
client.println(“<br /><b>Relè C: </b>”);
if(statoC == 0){
client.println(“<span style=’color:grey; font-weight:bold;’>OFF</span> – “);
client.println(“<a href=\”?C=1\”>Accendi</a> | “);
}else if(statoC ==1){
client.println(“<span style=’color:green; font-weight:bold;’>ON</span> – “);
client.println(“Accendi | “);
}
if(statoC == 0){
client.println(“Spegni”);
}else if(statoC ==1){
client.println(“<a href=\”?C=0\”>Spegni</a>”);
}

//D
client.println(“<br /><b>Relè D: </b>”);
if(statoD == 0){
client.println(“<span style=’color:grey; font-weight:bold;’>OFF</span> – “);
client.println(“<a href=\”?D=1\”>Accendi</a> | “);
}else if(statoD ==1){
client.println(“<span style=’color:green; font-weight:bold;’>ON</span> – “);
client.println(“Accendi | “);
}
if(statoD == 0){
client.println(“Spegni”);
}else if(statoD ==1){
client.println(“<a href=\”?D=0\”>Spegni</a>”);
}

//client.println(“<hr /><a href=\”/\”>Aggiorna</a>”);
client.println(“</div></body></html>”);
break;
}
if (c == ‘\n’){
currentLineIsBlank = true;
}else if (c != ‘\r’){
currentLineIsBlank = false;
}
}
}
readString=”";
delay(1);
client.stop();
}
}

Vabbè… si è perso tutta la formattazione nel copia e incolla ma se vi interessa vi mando via posta lo sketch.

La casa di DoMina

La casa di DoMina

Per ora tutto funziona a dovere.

Devo solo trovare una scatola elegante dove mettere tutto quanto.



Open Drum Machine Wireless Orchestra

aprile 8th, 2013

Domenica scorsa sono stato invitato a partecipare all’evento from MARKET to MAKERS, un evento sull’autoproduzione dal basso basato su strumenti e prodotti open source. Io sono stato invitato come musicista a presentare uno dei miei progetti basati su Arduino (come il midi mitra oppure Onda Quadra Posse).

Siccome mi piace reinventarmi, ho deciso di presentare un progetto nuovo, sempre basato su Arduino. Anche perchè le vecchie cose che avevo fatto erano fine a se stessi, e considerando il fatto che avevo già smontato tutto e perso lo schema elettrico.

Per tutta questa serie di ragioni ho ideato la Open Drum Machine Wireless Orchestra. Una performance in cui tutto il pubblico diventa parte integrante performativa dell’esibizione. Il concetto è semplice: accedendo ad una rete wireless opportunamente configurata tramite il proprio device (smartphone, tablet, pc) e accedendo ad un’apposita pagina web, si può interagire facendo suonare la batteria. E tutti i partecipanti agiscono sulla stessa batteria.

Per fare questo, coadiuvato dal mio amichetto nerd che però preferisce rimanere anonimo, ho configurato una Fonera installandoci OpenWRT, che forniva connettività wireless e assegnava ad ogni client connesso un indirizzo ip tramite l’apposito server DHCP e, tramite il server web, gestiva una pagina web sui cui girava una pagina statica che, con un click ad una immagine linkata, mandava la richiesta, tramite cavo ethernet, a un Arduino con lo shield ethernet. La richiesta http veniva convertita in segnale MIDI e inviato a Ableton Live installato sul computer. Ableton era configurato in modo da far partire un sample di batteria ad ogni impulso midi che gli arrivava.

odmwo

A tutto questo ho aggiunto una scheda makey makey, regalatami per il compleanno per far suonare loop tamarri di synth, come contorno per la batteria. L’idea era di prendere 4 persone, fargli tenere una parte del sensore, e dargli il 5 per far partire il loop assegnato a quel sensore. Per problemi legati alle masse o a inneschi o potrei inventarmi tantissime parole tecniche tanto non so da cosa è dipeso, quest’ultima parte della performance non è riuscita del tutto.

Ecco un video che spiega, forse, meglio:

Gestiolus 0.1 is out

novembre 7th, 2012

Da circa 3 anni sto usando e sviluppando a velocità bradipo un gestionale per tenere traccia degli interventi e delle riparazioni nei vari laboratori di computer che gestisco. Svariate volte mi è capitato che mi fosse segnalato un guasto che non potevo sistemare subito per un motivo o per un altro e io, viste le mie ristrette capacità mentali, spesso me ne dimenticavo o, ancora peggio, me lo scrivevo su un foglio di carta. Non sia mai che nel 2012 sia ancora costretto a scrivere su un foglio di carta.

Gestiolus LogoPer questo motivo ho creato Gestiolus.

Esistono altri sistemi già pronti per la gestione dei ticket o cose simili, di prodotti ce ne sono tipo migliaia, ma li ho sempre trovati macchinosi e non immediati. Certo erano adatti comunque alle mie esigenze ma non mi soddisfacevano appieno.

Volevo un prodotto semplice e immediato, che facesse solo quello di cui ho bisogno, e poco più. Mi serviva anche avere un form scollegato dal sistema che potesse essere usato da tutti per segnalare l’intervento (in realtà questa funzione non l’ho ancora implementata).

All’indirizzo http://minucci.net/gestiolus-demo/ si può provare una demo funzionante.

Con Gestiolus è possibile aggiungere e rimuovere i laboratori o le aule su cui intervenire e tenere traccia di chi ha effettuato l’intervento. Alla fine è possibile generare dei report sul numero di interventi chiusi da un determinato nominativo.

E’ scritto in php e mysql, con qualche puntina di javascript, e potete scaricarlo da qua: http://code.google.com/p/gestiolus/

Occhio che c’è anche il git da cui prendere la versione più aggiornata.

RockEat – il ritorno

maggio 3rd, 2012

RockEat aveva smesso di funzionare ma il team si è messo subito all’opera per trovare la soluzione fondendo insieme le menti. Con un brainstorming e un briefing via mail, e appontando un planning, si è arrivati a trovare nuovamente la soluzione.

In pratica hanno cambiato la PAROLASEGRETISSIMA, di cui parlavo anche nel post precedente a riguardo, con una nuova, che manterrò comunque segreta perchè mi piace l’idea di far parte di una elite di persone che ne sono al corrente.

Oltre ad aver cambiato la PAROLASEGRETISSIMA hanno aggiunto un header http per il referer, ovvero l’url da cui sei arrivato a una determinata pagina, il cui valore è l’url stesso del player flash. Se vi mettete a sbirciare dentro l’html è facile notare che il player flash è cambiato e ora è player3.swf.

Detto questo il resto è rimasto inalterato, bisogna sempre calcolarsi l’md5 dall’url del file con la PAROLASEGRETISSIMA in fondo.

Per fare il bullo ho voluto provare a fare uno script in bash su una sola riga per automatizzare lo scaricamento dei file, eccolo:

wget -O /tmp/site.html http://www.rockit.it/rivera/album/novembre-2011/19214 ; cat /tmp/site.html | grep “id_” | sed ‘s/id_/\n/g’ | sed ‘s/”><ul>/\n/g’ | awk ‘NR%2==0′ | awk -F”_” ‘{print “echo -n \”http://ww2.rockit.it/7mp3/” $2 “/” $1 “.mp3-PAROLASEGRETISSIMA\” | md5sum “}’ > /tmp/url.tmp ; sh /tmp/url.tmp | cut -f1 -d’ ‘ > /tmp/url.md5 ; cat /tmp/url.tmp | awk -F”\”" ‘{print $2}’ | awk -F”-” ‘{print $1}’ > /tmp/tmp.url ; paste -d ” ” /tmp/url.md5 /tmp/tmp.url > /tmp/url.tmp ; sed ‘s/\ /” /g’ /tmp/url.tmp | sed ‘s/^/wget –referer=http:\/\/www.rockit.it\/web\/js\/player3.swf –post-data rockitID=/’ /tmp/url.tmp > /tmp/wget.tmp ; sh /tmp/wget.tmp

Ovviamente dovete cambiare l’url dell’album. Funziona solo su Linux (su osx non so) e i file mp3 non li salva coi nomi corrispondenti ma va bene uguale, si presume che l’id3 tag dell’mp3 sia apposto.

Presto ci saranno in vendita le magliette di RockEat.

celsiutter

marzo 28th, 2012

Dopo settimane di lavorazione sono riuscito a costruire celsiutter, un coso con Arduino che posta in automatico la temperatura su twitter.

Cosa vi serve?

Lo schema è questo:

E’ piuttosto semplice. L’LM35 c’ha 3 terminali: uno è la massa, l’altra è l’alimentazione che può essere da 4 volt in su e il pin centrale è quello che riporta la temperatura, un grado per ogni centesimo di volt. Ovvero se ci attacchiamo col teste sul centrale e questo misura 0,22 volt vuol dire che ci sono 22 gradi. Semplice.

I due led sono attaccati su uscite digitali diverse e libere, perchè l’Ethernet Shield ne usa lui alcune, non ho ben capito quali, sono andato a tentoni provando quali fossero libere. Quello verde serve a segnalare se il post è riuscito e se invece ritorna degli errori si accende quello rosso.

Poi ho collegato l’AREF ai 3,3 volt perchè, il codice che ho palesemente copiato da qui riadattandolo un po’ alle mie esigenze, calcola la temperatura usando come riferimento i 5 volt di Arduino. Siccome nei primi esperimenti non mi tornavano le temperature giuste, ho notato che in realtà i 5 volt del mio Arduino sono 4,88 e quindi, dopo aver fatto il calcolo, il risultato era un po’ sballato. Per evitare questo ho usato i 3,3 come riferimento che sono più precisi, misurando col tester segna 3,29 volta che va più che bene.

Per twitter ho usato questa libreria, che funziona bene e il codice non è troppo complesso.

Ora ecco il codice:

#include <SPI.h>
#include <Ethernet.h>
#include <Twitter.h>
#include <stdlib.h>
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192, 168, 10, 222 };
Twitter twitter(“TwitterToken”);
int pin = 0;
int temp = 0;
char tempchar[] = “”;
char testo[] = “”;
char fine[] = “”;
char msg[82] = “”;
int ledpost = 13;
int lederror = 8;
int i = 0;

void setup()
{
delay(1000);
Ethernet.begin(mac, ip);
Serial.begin(9600);
analogReference(EXTERNAL);
pinMode(ledpost, OUTPUT);
pinMode(lederror, OUTPUT);
}

void loop()
{
digitalWrite(ledpost, HIGH);
digitalWrite(lederror, LOW);
temp=(3.3 *analogRead(pin) *100.00) / 1024.0;
String testo = “Messaggio automatico generato da Arduino: a casa mia sono “;
String fine = ” gradi centigradi. “;
testo += temp;
testo += fine;
testo += i;
testo.toCharArray(msg, 82);
Serial.println(msg);
Serial.println(“connecting …”);
if (twitter.post(msg)) {
int status = twitter.wait(&Serial);
if (status == 200) {
Serial.println(“OK.”);
digitalWrite(ledpost, LOW);
} else {
Serial.print(“failed : code “);
Serial.println(status);
digitalWrite(lederror, HIGH);
}
} else {
Serial.println(“connection failed.”);
digitalWrite(lederror, HIGH);
}
Serial.print(i);
Serial.println(” Pausa di un’ora”);
i=i+1;
delay(3600000);
}

(indentatelo voi che io non c’ho voglia :) ) (dove c’è scritto TwitterToken dovete metterci il vostro token, lo generate dal sito della libreria)(nella variabile byte ip[] dovete metterci un indirizzi ip valido della vostra lan).

Il problema più grosso l’ho avuto nella conversione del formato delle variabili. twitter.post() accetta solo una char(), mentre la temperatura è un int() e ho dovuto concatenarla con una String e poi riconvertire tutto in char(). Se avete un metodo meno macchino segnalatelo pure nei commenti.

Alla fine del messaggio da postare su twitter ci ho dovuto mettere un valore incrementale altrimenti twitter lo vede come duplicato e non me lo fa postare. In questo modo, forse non troppo elegante, ho risolto il problema e inoltre mi tiene un log di quanti post ha effettuato (ovviamente ogni volta che spegnete Arduino ricomincia a contare da 0).

E’ tutto.

OpenWrt su 3Com 3CRWER200-75

marzo 13th, 2012

Un bel giorno la rete qua impazzì. I ping andavano a caso, i pacchetti si duplicavano, non arrivavano a destinazione, robe così. Un gran putiferio. Alla fine, dopo mille prove, siamo arrivati a dare la colpa ad un vecchio router 3com che usavamo come access point. Tolto questo affare dalla rete e tutto è tornato a funzionare regolarmente.

Questo affare poi è stato riposto in un armadio tra la roba non funzionante. A me dispiace vedere questi aggegi dimenticati e, visto che sono un fanatico di OpenWrt, ho provato a mettercelo visto che, nel sito, c’era la procedura per il modello 3CRWER100-75. In realtà io avevo un 3CRWER200-75, non so cosa cambi esattamente, so solo che la procedura ha funzionato regolarmente. Ed ecco quello che ho fatto io.

Innanzitutto tenetevi aprire la pagina apposita sul wiki, scaricatevi il kernel e il root fs, poi dovete installarvi un server tftp, io ho usato tftpd-hpa e ho installato anche putty. Di solito putty lo usavo su windows, ma ho scoperto che esiste anche per Linux. Putty serve semplicemente come terminale telnet, non ho usato il normale telnet già compreso in linux per motivi che spiegherò più avanti.

A questo punto dovete resettare il router per riportarlo alle impostazioni di fabbrica. Per fare questo basta tenere premuto il solito bottoncino e poi gli si da corrente e lo si tiene premuto per circa 10 secondi. Non so perchè ma l’ho dovuto rifare 3 volte.

Adesso il router torna all’impostazione di default e ha l’indirizzo 192.168.1.1, un ping ve lo confermerà, sempre che non abbiate in rete già un altro dispositivo con lo stesso indirizzo.

Ora non dovete fare altro che spegnere e riaccendere il router e lanciare il telnet sulla porta 9000 in un lasso di tempo indefinito in cui redboot ascolta su quella porta e vi da accesso al prompt. Facendolo a mano richiede culo e tempismo, roba che ci becchi tipo 1 volta su 10. Appena avuto accesso bisogna premere CTRL+C. Ed è proprio qua l’inceppo, pare che il telnet non riesco a mandare CTRL+C al prompt per qualche strambo motivo di tabella di caratteri o roba del genere, c’è in giro anche un hack usando netcat ma ho provato e non ha funzionato.

Ed ecco la mia elegante soluzione:

Innanzitto lanciate putty e configuratelo come in questa schermata

In pratica dovete settargli l’indirizzo ip, 192.168.1.1, la porta 9000, dirgli di usare il protocollo telnet e infine salvate la sessione. Io l’ho chiamato telnet9000.

A questo punto aprite il terminale e scrivete questo barbatrucco:

arping -f 192.168.1.1; putty -load telnet9000

Questo fa in modo che appena arping si accorge che l’ho desiderato, l’192.168.1.1, diventa attivo, lancia putty caricandogli, -load telnet9000, la sessione che abbiamo salvato prima: il succo del discorso è che fa il telnet sulla porta 9000 al momento giusto.

A questo punto dovreste avere una schermata di questo tipo:

ovvero siete arrivati al prompt di RedBoot, che è quello che ci interessa.

Ora, pre trasferire l’immagine del kernel e del rootfs, abbiamo bisogno di un server tftp da cui attigente.

Installate, come me, tftpd-hda, non perchè sia meglio di altri ma solo perchè sono riuscito a farlo funzionare alla svelta. Quindi

sudo apt-get install tftpd-hpa

(sudo perchè tanto lo so che usate tutti Ubuntu) poi create una directory per la root del server tftp, io per comodità l’ho creata nella root del file system, quindi /tftpboot, e gli date tutti i permessi del mondo di lettura e scrittura, sennò poi non il client non è contento.

Poi editate il file /etc/default/tftpd-hpa e fatelo diventare più o meno come questo:

# /etc/default/tftpd-hpa

TFTP_USERNAME=”tftp”
#TFTP_DIRECTORY=”/var/lib/tftpboot”
TFTP_DIRECTORY=”/tftpboot”
TFTP_ADDRESS=”192.168.1.101:69″
#TFTP_OPTIONS=”–secure”

L’indirizzo ip 192.168.1.101 non è casuale. Se tornate a putty e al prompt di RedBoot e scrivete

fsconfig -l

vi apparirà una roba tipo questa:

Praticamente RedBoot viene già di default con delle impostazioni sue: l’ip, il gateway e le altre robe. A noi interessa la riga:

Default server IP address: 192.168.1.101

che, praticamente, vuol dire che lui si aspetta che il server tftp sia su quell’indirizzo. Ora noi potremo andarci a leggere la documentazione di redboot e di fsconfig perchè un modo per cambiare quella voce c’è sicuramente, ma chi ce lo fa fare? Basta cambiare l’indirizzo ip della propria macchina che è molto più semplice :) Da qui spiegato il motivo del file di configurazione tftpd-hpa.

A questo punto siamo già un pezzo avanti e possiamo seguire pedissequamente la guida di OpenWrt. Quindi:

fis init

e premete y, poi, al prompt, scrivete:

load -r -b %{FREEMEMLO} /tftproot/openwrt-atheros-vmlinux.lzma
fis create -r 0×80041000 -e 0×80041000 vmlinux.bin.l7
load -r -b %{FREEMEMLO} /tftproot/openwrt-atheros-root.squashfs
fis free
fis create -l 0x2E0000 rootfs
fis list
reset

i due comando load hanno bisogno comunque del percorso assoluto, mistero, altrimenti se la prende a male e non trova il file. Se load ritorna errori di lettura vuol dire che non avete dati abbastanza permessi alla directory /tftproot, provate anche a dargli un chown -R nobody eventualmente.

Dopo il reset il router si riavvia e farà il boot con OpenWrt. Attenzione che il boot sarà un po’ più lento rispetto al firmware originale.

Per accedere telnettate l’192.168.1.1 e avrete accesso al prompt di OpenWrt, leggete le robe scritte, settando la password, con passwd, si imposta la password e si attiva automaticamente il server ssh.

Ora avete un router con OpenWrt e potete farci un po’ quello che vi pare

rockeat

febbraio 8th, 2012

sottotitolo: rockit e gli mp3 #2

(la descrizione sarà un po’ sommaria perchè mica mi ricordo esattamente tutti i passi della nostra ricerca)

Ebbene si, abbiamo (io e @eroispaziali, ma più che altro lui che si è smazzato il grosso del lavoro) trovato il modo di scaricare gli mp3 da rockit da dopo il restiling grafico che, di fanno, vanifica il vecchio procedimento.

Questa volta è un pelo più complicato, ma andiamo con ordine e prendiamo una pagina di esempio: i fine before you came con l’album ormai (che tanto c’è da scaricare anche dal loro sito quindi non facciamo male quasi a nessuno).

cominciamo a sbirciare tra il codice html e a cercare la sezione in cui carica il player di mp3: ad un certo punto carica il file player.swf, che è il player vero e proprio, e poi comincia a disegnare l’interfacca al player, i bottoni play, i titoli e tutto il resto. ma fino  a questo punto non si capisce niente, sembra funzionare per magia, invece sbirciando in fondo alla pagina viene caricato una libreria in javascript: lib.js. fai 2 + 2 e viene quasi naturale sbirciarci dentro.

tra le tante funzioni ce n’è una interessante:

function player_initSWF($data, $textStatus, $jqXHR) {

la player_initSWF(); ma, a parte i parametri tra parentesi, a noi interessa più una riga commentata:

// console.log( $data.url );

Facendo scrivere quella variabile, con un po’ di magheggi con firebug o robe simili, si riesce a risalire all’url del file mp3.

a questo punto magari dici: “ah, è fatta”, e invece no.

Torniamo a sbirciare l’html, ad ogni brano corrisponde un id:

<li class=”item” id=”id_139208_4068″><ul><li class=”play”><a href=”#” rel=”139208″>Play</a></li><li class=”playlist”><a href=”#” rel=”nofollow”>Aggiungi</a></li><li class=”title”><a href=”/finebeforeyoucame/canzone/dublino/139208” class=”titolo” rel=”nofollow”>1. Dublino</a></li></ul></li>

A parte gli <li> annidati notiamo che ad ogni canzone corrisponde un id della canzone e un id dell’album. In questo caso 4066 è l’id dell’album, mentre 139208 è l’id dell’mp3 che, come per magia, corrispondono alla variabile $data.url della funzione in javascript.

Ma ancora niente download diretto. E niente, magheggiando con altre robe tipo  HttpFox o simile si riesce a scoprire che il file viene presto tramite POST e non tramite GET quindi.

Sempre nel file lib.js c’è questo:

$('body').append('<form id="godown" '+$response.t+'><input type="hidden" name="rockitID" value="'+$response.k+'"/></form>');

che altri non è che un campo POST nascosto, e non visibile dall’html, che specifica una stringa, un id chiamato appunto rockitID.

Ma come viene generato questo rockitID? Mistero. Abbiamo chiesto a Giacobbo e a prima vista sembra una semplice stringa md5 che, sappiamo tutti, non è reversibile.

Non so quante combinazioni di stringhe ho provato a convertire ma niente, nessuna ritornava quella giusta.

La soluzione consiste nel decompilare il file player.swf.

Ad un certo punto, dentro il file .swf, c’è questo:

_loc_1.rockitID = MD5.hash(this.fileURL + “-PAROLASEGRETISSIMA”);

Dove PAROLASEGRETISSIMA ovviamente non è PAROLASEGRETISSIMA ma una stringa di testo che mi piace di più tenere segreta: un po’ come le strette di mano dei moti carbonari, o il modo di allacciare le scarpe delle spie, o anche la tizia che guidava la jeep nella contea di Hazzard.

Quindi basta calcolare l’hash md5 aggiungendo la PAROLASEGRETISSIMA in fondo alla stringa e viene ritornato il rockitID giusto. A quel punto basta usare wget, o curl, passandogli come POST rockitID la stringa md5 risultante e l’url del file mp3.

Semplice. Ecco il risultato (però con un altro album che i Fine Before You Came ce li ho già):

Semplice? Ora che lo so è semplice, ma prima non lo era affatto :)

In questa sede mi preme ringraziare non tanto rockit, che comunque è da un po’ di tempo ormai che mette on line album che non mi interessano, ma piuttosto ringrazio @eroispaziali che mi ha dato lo stimolo e mi ha motivato per trovare la soluzione.

Un po’ come quando il capitano Picard spiega a non mi ricordo quale razza aliena che parte del senso della vita è risolvere i problemi che ti si presentano man mano. E con problemi non intendo le bollette da pagare, quello si risolve pagando la bolletta, ma problemi inteso come dice wikipedia:

Un problema, comunemente inteso, è un ostacolo che rende difficile raggiungere un determinato obiettivo o soddisfare una certa esigenza, frapponendosi tra la volontà dell’individuo e la realtà oggettiva.

Quindi non è che uno mi dice “ah, ma che sfigato, non hai nient’altro da fare?”, si e no. Faccio le cose che mi diverte fare: in questo caso riuscire a scaricare gli mp3 da rockit. Altri preferiscono truccare i motorini, altri passano il tempo a lucidare la macchina, altri guardano il grande fratello, altri fanno altre cose. Il mio non lo considero affatto tempo perso. Ognuno impiega il proprio tempo come preferisce.

Uno dei miei motti è: d’altronde gianni morandi mangia la merda.

Chi sono io per giudicarlo? :)

 

Update: leggetevi però anche questo prima di giudicare.

rockeat

febbraio 8th, 2012

sottotitolo: rockit e gli mp3 #2

(la descrizione sarà un po’ sommaria perchè mica mi ricordo esattamente tutti i passi della nostra ricerca)

Ebbene si, abbiamo (io e @eroispaziali, ma più che altro lui che si è smazzato il grosso del lavoro) trovato il modo di scaricare gli mp3 da rockit da dopo il restiling grafico che, di fanno, vanifica il vecchio procedimento.

Questa volta è un pelo più complicato, ma andiamo con ordine e prendiamo una pagina di esempio: i fine before you came con l’album ormai (che tanto c’è da scaricare anche dal loro sito quindi non facciamo male quasi a nessuno).

cominciamo a sbirciare tra il codice html e a cercare la sezione in cui carica il player di mp3: ad un certo punto carica il file player.swf, che è il player vero e proprio, e poi comincia a disegnare l’interfacca al player, i bottoni play, i titoli e tutto il resto. ma fino  a questo punto non si capisce niente, sembra funzionare per magia, invece sbirciando in fondo alla pagina viene caricato una libreria in javascript: lib.js. fai 2 + 2 e viene quasi naturale sbirciarci dentro.

tra le tante funzioni ce n’è una interessante:

function player_initSWF($data, $textStatus, $jqXHR) {

la player_initSWF(); ma, a parte i parametri tra parentesi, a noi interessa più una riga commentata:

// console.log( $data.url );

Facendo scrivere quella variabile, con un po’ di magheggi con firebug o robe simili, si riesce a risalire all’url del file mp3.

a questo punto magari dici: “ah, è fatta”, e invece no.

Torniamo a sbirciare l’html, ad ogni brano corrisponde un id:

<li class=”item” id=”id_139208_4068″><ul><li class=”play”><a href=”#” rel=”139208″>Play</a></li><li class=”playlist”><a href=”#” rel=”nofollow”>Aggiungi</a></li><li class=”title”><a href=”/finebeforeyoucame/canzone/dublino/139208” class=”titolo” rel=”nofollow”>1. Dublino</a></li></ul></li>

A parte gli <li> annidati notiamo che ad ogni canzone corrisponde un id della canzone e un id dell’album. In questo caso 4066 è l’id dell’album, mentre 139208 è l’id dell’mp3 che, come per magia, corrispondono alla variabile $data.url della funzione in javascript.

Ma ancora niente download diretto. E niente, magheggiando con altre robe tipo  HttpFox o simile si riesce a scoprire che il file viene presto tramite POST e non tramite GET quindi.

Sempre nel file lib.js c’è questo:

$('body').append('<form id="godown" '+$response.t+'><input type="hidden" name="rockitID" value="'+$response.k+'"/></form>');

che altri non è che un campo POST nascosto, e non visibile dall’html, che specifica una stringa, un id chiamato appunto rockitID.

Ma come viene generato questo rockitID? Mistero. Abbiamo chiesto a Giacobbo e a prima vista sembra una semplice stringa md5 che, sappiamo tutti, non è reversibile.

Non so quante combinazioni di stringhe ho provato a convertire ma niente, nessuna ritornava quella giusta.

La soluzione consiste nel decompilare il file player.swf.

Ad un certo punto, dentro il file .swf, c’è questo:

_loc_1.rockitID = MD5.hash(this.fileURL + “-PAROLASEGRETISSIMA”);

Dove PAROLASEGRETISSIMA ovviamente non è PAROLASEGRETISSIMA ma una stringa di testo che mi piace di più tenere segreta: un po’ come le strette di mano dei moti carbonari, o il modo di allacciare le scarpe delle spie, o anche la tizia che guidava la jeep nella contea di Hazzard.

Quindi basta calcolare l’hash md5 aggiungendo la PAROLASEGRETISSIMA in fondo alla stringa e viene ritornato il rockitID giusto. A quel punto basta usare wget, o curl, passandogli come POST rockitID la stringa md5 risultante e l’url del file mp3.

Semplice. Ecco il risultato (però con un altro album che i Fine Before You Came ce li ho già):

Semplice? Ora che lo so è semplice, ma prima non lo era affatto :)

In questa sede mi preme ringraziare non tanto rockit, che comunque è da un po’ di tempo ormai che mette on line album che non mi interessano, ma piuttosto ringrazio @eroispaziali che mi ha dato lo stimolo e mi ha motivato per trovare la soluzione.

Un po’ come quando il capitano Picard spiega a non mi ricordo quale razza aliena che parte del senso della vita è risolvere i problemi che ti si presentano man mano. E con problemi non intendo le bollette da pagare, quello si risolve pagando la bolletta, ma problemi inteso come dice wikipedia:

Un problema, comunemente inteso, è un ostacolo che rende difficile raggiungere un determinato obiettivo o soddisfare una certa esigenza, frapponendosi tra la volontà dell’individuo e la realtà oggettiva.

Quindi non è che uno mi dice “ah, ma che sfigato, non hai nient’altro da fare?”, si e no. Faccio le cose che mi diverte fare: in questo caso riuscire a scaricare gli mp3 da rockit. Altri preferiscono truccare i motorini, altri passano il tempo a lucidare la macchina, altri guardano il grande fratello, altri fanno altre cose. Il mio non lo considero affatto tempo perso. Ognuno impiega il proprio tempo come preferisce.

Uno dei miei motti è: d’altronde gianni morandi mangia la merda.

Chi sono io per giudicarlo? :)

 

Update: leggetevi però anche questo prima di giudicare.

Update: è cambiato tutto di nuovo, tenetevi aggiornati.

Arduino Vj System

gennaio 6th, 2012

Sono mesi che avevo in mente questo progetto usando Arduino e la libreria TV Out, finalmente sono riuscito a produrre qualcosa di funzionante ed è anche giunta l’ora di rendere pubblico il tutto.

La libreria per il tv out serve, come si intuisce dal nome, a generare dei segnali video. Vista la scarsa potenza di Arduino, si riescono soltanto a generare segnali video in bianco e nero e con una risoluzione di 128×96 pixel. Per capirci si riescono a fare cose come questo o questo o quest’altro. Sono vecchi esperimenti che avevo fatto tempo fa. E’ roba molto limitata ma, visti i limiti, la sfida diventa ancora più interessante.

La mia idea era costruire un coso da utilizzare come visual durante un concerto. La definizione di vj di wikipedia è abbastanza esaustiva. In pratica un affare con dei comandi per interagire in tempo reale, o quasi, con gli effetti video generati da Arduino.

Questo è il risultato:

Per comodità ho scelto di costruire il circuito su una millefori da inserire direttamente su Arduino. Nella foto si possono vedere i 3 switch per selezionare gli effetti, il connettore RCA giallo per l’uscita video, il potenziometro per regolare la velocità dell’effetto e il led verde che segnala l’accensione – il led rosso in realtà non serve a niente.

Questo è lo schema:

Per disegnarlo ho usato Fritzing e potete anche scaricarvi il file con gli schemi.

Per ottimizzare ho usato solo 3 interruttori coi quali si possono selezionare 8 diversi effetti video. Ecco l’elenco:

  • 000: face();
  • 001: point();
  • 010: strobo();
  • 011: star();
  • 100: square();
  • 101: bug();
  • 110: cube();
  • 111: circle();

(le prime tre cifre indicano lo stato degli switch A, B e C; 0 è spento, 1 è acceso)

Potete scaricarvi il sorgente per Arduino. Dentro il codice ci sono varie funzione che si chiamano nello stesso modo elencato qui sopra. Da notare l’effetto bug() che in realtà doveva fare tutt’altro, almeno per come l’avevo pensato, ma per colpa di non so quale bug genera un effetto video che non mi dispiaceva affatto, per cui l’ho lasciato così com’è.

Per l’effett face() ho tentato di usare la funzione interna della libreria TV Out per caricare le bitmap, opportunamente convertite, ma non ci sono riuscito per cui, visto che dovevo sbrigarmi a finire tutto l’ambaradan, ho optato per un sistema empirico: tipo che disegno le faccie pixel per pixel, questo ovviamente ha portato ad un riempimento smodato della memoria di Arduino tant’è che ci sono state solo due faccie :) .

Ecco il risultato proiettato dal vivo durante il nostro concerto:

Al minuci 3:05 si può vedere l’effetto bug() in azione.

Se vi interessa qua, qua, qua e qua ci sono le parti rimanenti del concerto.

Ogni tanto, mettendo in sequenza alcuni effetti video, Arduino perdeva il controllo, credo per il troppo casino a video, e bisognava resettare tutto il sistema.

rockit e gli mp3

maggio 13th, 2011

su rockit.it, sappiamo più o meno tutti, spesso mettono dei dischi da ascoltare in streaming, spesso in anteprima rispetto all’uscita del disco. questa è cosa buona e giusta, ma ho scoperto un modo per scaricarsi i file mp3 così da poterseli metterli anche nell’ipod, senza dover ascoltare quel determinato album in streaming.

trovare i file è semplice, prendendo come esempio l’album Legna dei Gazebo Penguins (che è comunque disponibile scaricarsi dal loro sito ufficiale), diamo un occhio al codice html.

il trucco sta nel trovare la stringa passata al lettore flash, esattamente questa riga javascript qua:

var so = new SWFObject(‘/mediaplayer/mp3player.swf?file=%2Fmediaplayer%2Frockit_pl.php%3Fx%3Da16253′,’mpl’,’240′,’22′,’9′);

come è facilmente intuibile il valore di file è un url encondato con i corrispondeti valori ascii per le slash, per il punto interrogativo e per l’uguale.

%2F corrisponde a /

%3F corrisponde a ?

%3D corrisponde a =

detto questo basta convertire quell’url e come risultato abbiamo:

/mediaplayer/rockit_pl.php?x=a16253

da qua è facile, abbiamo lo script rockit_pl.php che, probabilmente, richiamare dal database l’id col valore 16253 e poi ne genera un file xml formattato in maniera opportuna da passare al player in flash. la x è un nome di variabile che viene passata allo script in php, mentre la a prima del numero ignoro cosa sia ma, in fondo, non ci interessa.

aggiungendo prima dell’url il soffisso del dominio di rockit, ci viene restituito un comodo file xml e, aprendolo con un editor di testo qualsiasi, vediamo che sono disponibili tutti i link ai file mp3 e, quindi, disponibili al download.

il formato dei file magari è scomodo perchè, scaricandoli a mano, avremo tanti file chiamati play.mp3, ma questo ci interessa a poco.

salta subito all’occhio, almeno a me, che il numeretto passato allo script php è uguale a quello che compare nell’url della pagina con lo streaming, quindi basta prendere il numeretto da qualsiasi altra pagina con lo streaming, sostituirlo, e otteniamo il file xml.

ora capisco che tutto questo giro di roba è scomodo e complicato quindi ho preparato questo semplice script in bash, quindi funzionante solo con linux (o al massimo anche con macosx ma ha bisogno di wget che bisogna installare tramite i macports). ecco il codice:

echo "wget -O /tmp/xml.tmp http://www.rockit.it/mediaplayer/rockit_pl.php?x=" | tr 'n' 'a' > /tmp/rockit.xml && echo "http://www.rockit.it/album/16253/gazebo-penguins-legna" | cut -d "/" -f 5 >> /tmp/rockit.xml ; sh /tmp/rockit.xml ; cat /tmp/xml.tmp | egrep 'title>[0-9]|url' | sed 's/ /_/g' | sed "s/'//g" | sed 's/<title>/wget -O /' | sed 's/</title>/.mp3/' | sed 's/n//' | sed 's/" />//' | sed 's/<media:content_url="/"/' | sed 's/"_/>/";/' | tr 'n' ' ' > /tmp/download.mp3 ; sh /tmp/download.mp3

è tutto in una riga solo perchè volevo provare a fare il bullo ma non ci sono riuscito del tutto.

questo script ha bisogno dell’url della pagina dello streaming da cui estrapola il file xml, parsa gli url, e salva gli mp3 col nome giusto nella directory in cui si lancia lo script.

avrei voluto farlo in php per renderlo più agevole ma tutti i miei host non permettono la fopen() al di fuori dell’host per cui non so come aprire il file xml. poi con uno script in bash lo lancio e posso dimenticarmi che sta runnando fino alla fine del download.

tutto qua

update: l’aggiornamento lo trovate qua