venerdì 15 luglio 2016

Servo Shield per Arduino

Avevo gia' provato ad usare i servo sia in modo diretto che tramite una scheda apposita. Questa volta devo realizzare un movimento PTZ per una webcam

Questa e' la volta dell'Adafruit Servo Shield (o meglio di un suo clone cinese)
La scheda, che funziona sul I2C, riesce a pilotare 16 canali da 0 a 15 a ciascuno dei quali corrisponde un servo



Arduino non eroga abbastanza tensione per cui e' necessario connettere una alimentazione esterna allo shield. Nel mio caso ho usato un modulo MB102 da breadboard collegato ad alimentatore da 2 A/12 V per pilotare due servo. Puo' essere anche necessario inserire un condensatore

Questa e' la pedinatura con il cavo giallo (dati) verso l'interno della scheda ed il cavo marrone (GND) sull'esterno)



Fatte le connessioni si deve scaricare la librerie apposita da Adafruit
Quiesto e' lo sketch che ho usato..si devono definire i valori minimi e massimi di rotazione (da riccercare per tentativi)


----------------------------------------------------
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x40);

#define SERVOMIN  200
#define SERVOMAX  400

void setup() {
  pwm.begin();
  pwm.setPWMFreq(60);  // Analog servos run at ~60 Hz updates
  yield();
}


void loop() {
  for (uint16_t pulselen1 = SERVOMIN; pulselen1 < SERVOMAX; pulselen1++) {
         pwm.setPWM(1, 0, pulselen1);
         delay(20);



        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
              pwm.setPWM(0, 0, pulselen);
              delay(20);
              }
        delay(500);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
              pwm.setPWM(0, 0, pulselen);
              delay(20);
              }
         delay(500);
  }

  for (uint16_t pulselen1 = SERVOMAX; pulselen1 > SERVOMIN; pulselen1--) {
         pwm.setPWM(1, 0, pulselen1);
         delay(20);



        for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
              pwm.setPWM(0, 0, pulselen);
              delay(20);
              }
        delay(500);
        for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
              pwm.setPWM(0, 0, pulselen);
              delay(20);
              }
         delay(500);
  }

}
----------------------------------------------------

lunedì 11 luglio 2016

Raggi cosmici e Android

Avevo sentito della possibilita' di usare il CCD della fotocamera dei comuni telefoni per individuare i raggi cosmici (o meglio i muoni che sono l'effetto dell'interazione del raggio cosmico con l'atmosfera.. quando un muone colpisce un CCD libera degli elettroni che sono misurabili dall'elettronica della fotocamera..per una descrizione piu' dettagliata si veda questo documento)

Questo effetto e' particolarmente visibile nelle fotografie riprese sulla stazione spaziole (i pixel, nella foto sottostante,  bruciati dal passaggio di raggio cosmico sono indicati dal cerchietto rosso).




Per vedere se riuscivo a catturare qualche evento ho usato l'applicazione DECO dell'Universita' del Winsconsin. Si tratta di un sistema di rilevazione distribuito che invia i dati ad un server centrale per discriminare i veri eventi dai falsi positivi



Il problema principale e' che il CCD, ovvero la sua matrice di sensori (ovvero i pixel), non sono tra loro calibrati e si deve quindi estrapolare dal rumore di fondo un eventuale evento.

Nonostante le bassa probabilita' di registrare un evento ho ottenuto nel giro di poche ore 6 eventi su  7770 osservazioni. O sono fortunato o c'e' qualcosa da capire.
Scaricando i dati dal sito a questo indirizzo queste sono le immagini relative ai miei eventi

Dati originali




Rielaborazione 
Rimettendo in ordine i dati all'interno di una GIF animata si vede chiaramente che alcuni punti a luminanza maggiori compaiono su diversi fotogrammi

Se si cerchiano di verde i pixel ad alta luminanza e si sottraggono dalle immagini delle acquisizioni reali si nota che, quelli indicati come eventi in realta' non sarebbero nient'altro che pixel fuori calibrazione all'interno della matrice dato che si trovano nella stessa posizione ed hanno una posizione reciproca uguale (e' altamente improbabile che un evento si ripeta nella stessa posizione della matrice nell'arco di un cosi' poco tempo, circa 3 ore di osservazione)

Visto che ho la fortuna di lavorare con colleghi che manipolano sostanze blandamente radioattive ed ho esposto il sensore della macchina fotografica ad un campione test di Cs137 in modo da forzare l'eccitazione dei pixel del CCD.

In questo modo, dal rumore di fondo, ogni tanto compaiono dei pixel piu' luminosi


Ancora una volta mettendo in fila le immagini si vede che il pixel piu' luminoso e' sempre il solito.





Non si tratta quindi dell'eccitazione derivante dal passaggio di una particella o radiazione ma di un errore del sensore della camera

In conclusione esperimento non riuscito
Per la cronaca ho provato a contattare gli sviluppatori di DECO sia sulla mailing list di Google che alla mail di riferimento ma non ho ottenuto risposta da circa 7 giorni. Peraltro le mie sono state le uniche registrate per 5 giorni consecutivi... non so quanto il progetto sia ancora attivo

Intel Compute Stick ed Ubuntu

Ho preso su Ebay per un cinquantina di euro (arrivato nuovo ed impacchettato.. il prezzo su Ebay e' di 136 euro)  e' di un Intel Compute Stick, piu' nel dettaglio il modello BOXSTCK1A32WFC con incluso un processore Atom con 2 Gb Ram, 32 Gb di disco e sistema operativo Windows 10...ne esiste anche una  versione con premontato Ubuntu ma costa circa uguale e monta solo 1 Gb Ram e 8Gb di disco


Primi dettagli: per usare l'adattore HDMI2VGA ho dovuto comprare un connettore HDMI femmina-femmina


Il modulo non e' proprio parco nei consumi. In fase di boot arriva anche a 1.2 A

Un altro problema e' che il Intel Compute Stick monta una sola USB 2 da 500 mA. Se si monta un Hub USB passivo e si collegamento mouse stampante e network dongle non si riesce ad alimentare il tutto...me ne sono accorto perche' il led sotto il mouse era spento. La soluzione e' quella di usare una HUB alimentato o tastiera e mouse Logitech con Universal Receiver oppure tutto bluetooth (in questo caso pero' non si riesce ad entrare nel BIOS)

Per Compute Stick esiste una apposita distribuzione Linuxium ma ho voluto comunque provare con una Ubuntu 16.04 64 bit standard per vedere come andava.
Per avviare il boot da BIOS si deve selezionare l'apposita opzione (vedi immagine sottostante) Configuration/Select Operating System


Visto che non volevo compromettere l'installazione di Windows 10 ho inserito una SD Card da 16 Gb ed ho installato il sistema con le impostazioni dello screenshot sottostante (la SD Card non e' cosi' lenta nell'uso)




Il sistema si e' installato e riavviato senza problemi tranne il fatto che GRUB, pur presentando l'opzione Windows non riusciva ad avviarlo (leggendo sembra che sia un problema legato a 32/64 bit)
Ubuntu 16.04 funziona bene tranne per il fatto che mancano i moduli per gestire la scheda WiFi e Bluetooth di Compute Stick. Una volta scoperto che il chip interno e' un Realtek 8723bs e' facile trovare i moduli da scaricare e compilare

Wifi
Bluetooth


Cercando di risolvere il problema di Grub e non volendo usare una soluzione preconfenzionata ho provato ad usare Ubuntu 16.04 da questo link ma Grub ha presentato sempre i soliti problemi



DXL335 con Arduino FIO

Un semplice progettino per un accelerometro accoppiato a XBee.
Per questa configurazione e' stata scelta una Arduino Fio, purtroppo oramai fuori produzione, una scheda che monta il microcontrollore di Arduino Leonardo accoppiato ad un socket Xbee con un connettore JST per una batteria LiPo e la predisposizione per il pannello solare


Il modulo Xbee non e' presente nella foto per far vedere il socket. il cavo blu in origine era tra DTS di Xbee e D10 per mandare il sleep mode il modulo di trasmissione)

La Arduino FIO si programma tramite FTDI Breakout (i pin devono essere saldati a mano).
L'ADXL e' stato brutalmente saldato ai pin A5, A6 ed A7 per i canali rispettivamente Z,Y ed X mentre per l'alimentazione ho fatto un paio di patch

Come si deve dal confronto con la moneta da due euro la dimesione totale del progetto e' estremamente ridotta (la batteria LiPo e' da 1400 mAh)


Lo sketch e' molto semplice e si limita ad effettuare una lettura analogica su ogni asse (per la conversione in accelerazione si veda questo precedente post) e mandare la lettura sulla porta seriale che e' direttamente collegata, senza modificare niente al modulo XBEE
------------------------------------------------------
void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.print(analogRead(A7));
  Serial.print("\t");
  Serial.print(analogRead(A6));
  Serial.print("\t");
  Serial.print(analogRead(A5));
  Serial.println();
  delay(100);
}




lunedì 4 luglio 2016

Checksum di stringhe NMEA e pacchetti UBX

Visto che mi trovo a trasmettere dati GPS via radio e' necessario verificare che i dati non siano stati corrotti. Un metodo semplice e' quello di calcolare il checksum delle stringhe NMEA e dei pacchetti Ublox


NMEA
--------------------------------------------------
il checksum delle stringhe NMEA e' piuttosto semplice. Prima di tutto la stringa e' terminata da 0d e 0a.

Prendiamo per esempio la stringa
$GNVTG,,T,,M,0.005,N,0.010,K,A*39

il checksum e' 39

per il calcolo si toglie il primo carattere $ e tutto cio' che e' dopo il carattere *.
si prendono poi i caratteri e si effettua uno XOR di ogni carattere della stringa (in esadecimale)


quindi 47 XOR 4e XOR 56 XOR 54 XOR 47 ....... = 39

in questo caso il checksum calcolato e' uguale dal checksum ricevuto, Cio' vuol dire che il pacchetto e' stato ricevuto correttamente
--------------------------------------------------


UBX
I pacchetti UBX sono di tipo binario e non hanno una lunghezza fissa
I pacchetti partono con i due caratteri B5 e 62, seguono due byte che identificano la classe del messaggio e l'ID del messaggio. Seguono poi due bytes che indicano la lunghezza del messaggio (inteso solo come il payload), il payload e due bytes finali di checksum (8 bit unsigned)

Quindi il payload parte dal byte 7 in formato 16 bit senza segno in formato Little Endian



L'algoritmo di checksum e' quello di Fletcher.
Questa e' la versione scritta nel manuale Ublox

ma il codice piu' corretto dovrebbe essere il seguente, che rinormalizza ad ogni passaggio con il modulo 255





Wired Ethernet su Intel Edison

Come prova ho provato a connettere via cavo Ethernet la Edison utilizzando un dongle USB-Ethernet

Il primo tentativo (ricordarsi di spostare il selettore verso la porta USB standard per attivarla) , utilizzando un dongle Lenovo USB 3 che usa il modulo cdc_ether, non e' andato a buon fine perche' il modulo non era riconosciuto dal kernel



Successivamente ho provato con un vecchio dongle USB-Ethernet di Apple che utilizza il modulo Asix  AX 88772 che e' stato immediatamente riconosciuto


[  872.328790] usb 1-1: new high-speed USB device number 3 using dwc3-host
[  872.368156] usb 1-1: New USB device found, idVendor=05ac, idProduct=1402
[  872.368187] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  872.368209] usb 1-1: Product: Apple USB Ethernet Adapter
[  872.368228] usb 1-1: Manufacturer: Apple Inc.     
[  872.368247] usb 1-1: SerialNumber: 019F66
[  873.250659] asix 1-1:1.0 eth0: register 'asix' at usb-dwc3-host.2-1, ASIX AX88772 USB 2.0 Ethernet, 00:1f:5b:ff:27:2e
[  873.379958] systemd-udevd[410]: renamed network interface eth0 to enp0s17u
1

Peraltro il dispositivo ha assunto direttamente l'IP da DHCP
-----------------------------------------------
root@edison:~# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: sit0: <NOARP> mtu 1480 qdisc noop
    link/sit 0.0.0.0 brd 0.0.0.0
3: wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 98:f1:70:67:20:fb brd ff:ff:ff:ff:ff:ff
    inet 192.168.43.200/24 brd 192.168.43.255 scope global wlan0
       valid_lft forever preferred_lft forever
4: usb0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 02:00:86:73:47:06 brd ff:ff:ff:ff:ff:ff
    inet 192.168.2.15/24 brd 192.168.2.255 scope global usb0
       valid_lft forever preferred_lft forever
5: enp0s17u1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000
    link/ether 00:1f:5b:ff:27:2e brd ff:ff:ff:ff:ff:ff
    inet 10.200.4.12/16 brd 10.200.255.255 scope global enp0s17u1
       valid_lft forever preferred_lft forever
    inet6 fe80::21f:5bff:feff:272e/64 scope link
       valid_lft forever preferred_lft forever

-----------------------------------------------

A questo puo' essere comodo disabilitare la connessione WiFi con i seguenti comandi

systemctl start connman
systemctl enable connman
connmnanctl
connmanctl> disable wifi




venerdì 1 luglio 2016

Android 6.0.1 su Nexus 5

Visto il calo dei prezzi mi sono preso un Nexus 5 32 Giga per sviluppo su Android 6




Il telefono era nuovo e quindi all'accensione e' iniziata la fila degli aggiornamenti che, partendo dalla versione 4.4, mi avrebbero preso un bel po' di tempo via OTA.
Durante un aggiornamento incrementale di Android 4.4.3 il telefono si e' riacceso con il robottino con la pancia aperta e la scritta Errore in rosso. 2 minuti di panico e poi il sistema si e' riavviato da solo

Non volendo ripetere l'esperienza e per risparmiare tempo ho provato a fare direttamente il salto a 6.0.1 evitando le OTA.

Dopo aver scaricato il file https://dl.google.com/dl/android/aosp/hammerhead-mob30m-factory-8fc48e44.tgz  (579 Mb) ed averlo scompattato ho seguito questi passi

adb reboot bootloader
fastboot oem unlock
./flash-all

bisogna armarsi di pazienza prima di riottenere il dispositivo funzionate (circa 20 minuti).