lunedì 14 agosto 2017

Riparazione Drone Husban Q4 Cam H111C

Mi sono comprato, con la scusa di fare giocare i bambini, un piccolo drone con fotocamera per la modica cifra di una ventina di euro, un Husban Q4 H111C . Non mi aspettavo niente di particolarmente solido ma dopo nemmeno un'ora di volo effettivo, durante il volo il motore posteriore di destra si e' piantato causando ovviamente la caduta del drone

Moneta per confronto delle dimensioni

visto il costo modesto del dispositivo la prima idea e' stata quella che fosse morto il motore e, visto il costo, lo avevo considerato come non recuperabile (si fa prima a comprarne un altro). Un paio di giorni dopo, osservando meglio, il problema e'  stato causato dalla disconnessione di uno dei fili dell'alimentazione del motore...e' bastato un punto di saldatura e' tutto e' ripartito.

Lato inferiore con i motori a vista

Il limite piu' serio di questo dispositivo e' che di fatto di atterra (o meglio ci si schianta) sempre battento sulla parte inferiore dei motori senza nessun sistema di ammortizzamento. E' per questo che il filo si e' dissaldato.

Un'altra cosa non scritta nel manuale: per effettuare riprese video si deve inserire una SD card. veloce. Io avevo recuperato una vecchie e lenta SD da 2 Gb ed i video venivano troncati dopo pochi secondi..passato ad una class 10 da 16 Gb il problema non si e' piu' riposto (ps. scritto troppo alla svelta..il cambio SD ha migliorato le cose ma non mi e' tuttora possibile registrare con continuita')



martedì 8 agosto 2017

Checksum su pacchetti UBX Ublox

Circa un anno fa avevo riportato il metodo di calcolo del CRC per i pacchetti dei GPS Ublox

Adesso riporto il codice di calcolo in Python

Esempio di pacchetto UBX


In pratica si procede a scorrere lo stream dei dati fino a raggiungere il pacchetto di sincronia dati definito dai due byte successivi 0xB5-0x62 (oppure in decimanle 181 e 98).
I byte successivi indicano

1 byte = classe pacchetto
1 byte = id pacchetto
2 byte = lunghezza del payload (LSB+MSB)

segue poi il payload della lunghezza calcolata come in precedenza

2 byte di CRC

attenzione: per il calcolo del CRC si devono escludere i primi due byte di sync e gli ultimi due byte di CRC.

il codice in Pyton e' il seguente
-----------------------------------------------------------
# coding=utf-8
with open("c:\Python27\COM.ubx", "rb") as binary_file:
    data = binary_file.read()

msg = []

for x in range(0,100):
    test =  data[x]
    if ((data[x] == 181) and (data[x+1] == 98)):
        print("Sync Found! B5 62")
        msg_cls = data[x+2] #classe
        msg_id = data[x+3] #id
        msg_len_lsb = data[x+4] #byte meno significativo lunghezza messaggio
        msg_len_msb = data[x+5] #byte piu' significativo lunghezza messaggio
        len_msb = msg_len_lsb + (msg_len_msb*256)+4   #lunghezza messaggio
        for t in range(0,len_msb):
            msg.append(data[x+2+t]) # salva il payload 
        msg_chk1 = data[x+len_msb+2] #estrai i due byte di checksum
        msg_chk2 = data[x+len_msb+3]    
        
        #calcolo del checksum del payload
        CK_A,CK_B = 0, 0
        for i in range(len(msg)):
            CK_A = CK_A + msg[i]
            CK_B = CK_B + CK_A
        CK_A = CK_A & 0xFF
        CK_B = CK_B & 0xFF

        # controlla se il CRC del pacchetto e quello calcolato coincidono    
        if ((CK_A == msg_chk1) and (CK_B == msg_chk2)):
            print("Pacchetto ok")

giovedì 3 agosto 2017

Galileo su Ublox M8T

per poter abilitare la ricezione del segnale della costellazione Galileo su Ublox M8T si deve aggiornare il software alla versione 3.01.
Per fare cio' si deve scaricare il firmware dal sito Ublox e poi da U-Center si avvia Flash Firmware Update. In firmware image si deve puntare al file scaricato mentre il file flash.xml da inserire nella casella Flash definition file si trova all'interno della cartella di installazione di Ublox



Una volta terminato il tutto  si abilita la ricezione del segnale Galileo a fianco di Glonass e GPS


Si puo' verificare che il nuovo firmware sia stato correttamente installato  andando nei messaggi UBX->MON->VER


A questo punto succede una cosa un po' strana...guardando i grafici non compare mai nessun satellite con la sigla che inizia per E (i Galileo si riconoscono per la lettera E seguita da un numero) ma andando un UBX->RXM->RAWX si vedono chiaramente comparire i Galileo (per esempio nell'immagine sottostante E18-E08-01)








mercoledì 2 agosto 2017

Clone cinese Lilypad

Per un progettino "indossabile" mi sono deciso a comprarmi una Arduino Lilypad...il problema e' come al solito che l'originale costa un botto e ci sono alternative piu' economiche


Il problema, come si vede chiaramente dal video sottostante, e' che il dispositivo, seppur funzionante, non e' una su basetta flessibile ma e' semplicemente un PCB rigido tagliato di forma rotonda (ascoltare l'audio dell'impatto sul tavolo)


la vera Lilypad fa questo


in buona sostanza da non ricomprare ed una stella su Amazon

Kotlin su Android Studio 2

Come aggiungere il supporto a Kotlin in Android Studio 2

Per prima cosa da File/Preferences si cercano i plugin e si installa JetBrains Plugin. Fatto cio' appare nella colonna di destra il plugin di Kotlin da poter installare


Fatto cio', per convertire un progetto Android/Java in Android/Kotlin, si crea un normale progetto, successivamente con la combinazione cmd+shift+A (in Mac) si cerca Convert Java File to Kotlin

L'IDE a questa punto richiede di risincronizzare il progetto



ed il codice Java viene convertito in Kotlin. Al monte di compilare viene anche chiesto di aggiornare gradle
il codice di un semplice esempio che cambia la stringa di una textview e' il seguente

package innocenti.luca.com.kot_test

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val testo: TextView = findViewById(R.id.textView) as TextView;
        testo.setText("Luca");

    }
}


martedì 1 agosto 2017

TI PS-6200 32Kb

Ogni tanto i cestini della spazzatura continuano a regalare soddisfazioni agli amanti di hardware obsoleto. E' oggi il caso di un Texas Instruments PS-6200 con 32 Kb di memoria.
Si tratta di un organizer (agenda, todo, calcolatrice, orologio, memo) del 1991 (e' una prima serie, si riconosce dalla posizione del logo sopra il display) e monta un processore derivato da Z80 (anche se ovviamente non ha una modalita' programmazione essendo una agenda elettronica e non una calcolatrice)

Il splendide condizioni di conservazione una volta inserite le batterie (due CR-2025) e' tornata a funzionare senza problemi







giovedì 27 luglio 2017

FFT su Arduino

Usando sempre come input il microfono amplificato ho provato la libreria ArduinoFFT ed in particolare l'esempio FFT_03 modificando il numero di samples a 128 e la frequenza di campionamento a 9600


--------
/*

Example of use of the FFT libray to compute FFT for a signal sampled through the ADC.
        Copyright (C) 2017 Enrique Condes

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "arduinoFFT.h"

arduinoFFT FFT = arduinoFFT(); /* Create FFT object */
/*
These values can be changed in order to evaluate the functions
*/
#define CHANNEL A0
const uint16_t samples = 128; //This value MUST ALWAYS be a power of 2
double samplingFrequency = 9600;

unsigned int delayTime = 0;

/*
These are the input and output vectors
Input vectors receive computed results from FFT
*/
double vReal[samples];
double vImag[samples];

#define SCL_INDEX 0x00
#define SCL_TIME 0x01
#define SCL_FREQUENCY 0x02

void setup()
{
  if(samplingFrequency<=1000)
    delayTime = 1000/samplingFrequency;
  else
    delayTime = 1000000/samplingFrequency;
  Serial.begin(115200);
  Serial.println("Ready");
}

void loop()
{
  for(uint16_t i =0;i<samples;i++)
  {
    vReal[i] = double(analogRead(CHANNEL));
    if(samplingFrequency<=1000)
      delay(delayTime);
    else
      delayMicroseconds(delayTime);
  }
  /* Print the results of the sampling according to time */
  Serial.println("Data:");
  PrintVector(vReal, samples, SCL_TIME);
  FFT.Windowing(vReal, samples, FFT_WIN_TYP_HAMMING, FFT_FORWARD); /* Weigh data */
  Serial.println("Weighed data:");
  PrintVector(vReal, samples, SCL_TIME);
  FFT.Compute(vReal, vImag, samples, FFT_FORWARD); /* Compute FFT */
  Serial.println("Computed Real values:");
  PrintVector(vReal, samples, SCL_INDEX);
  Serial.println("Computed Imaginary values:");
  PrintVector(vImag, samples, SCL_INDEX);
  FFT.ComplexToMagnitude(vReal, vImag, samples); /* Compute magnitudes */
  Serial.println("Computed magnitudes:");
  PrintVector(vReal, (samples >> 1), SCL_FREQUENCY);
  double x = FFT.MajorPeak(vReal, samples, samplingFrequency);
  Serial.println(x, 6);
  while(1); /* Run Once */

}

void PrintVector(double *vData, uint8_t bufferSize, uint8_t scaleType)
{
  for (uint16_t i = 0; i < bufferSize; i++)
  {
    double abscissa;
    /* Print abscissa value */
    switch (scaleType)
    {
      case SCL_INDEX:
        abscissa = (i * 1.0);
break;
      case SCL_TIME:
        abscissa = ((i * 1.0) / samplingFrequency);
break;
      case SCL_FREQUENCY:
        abscissa = ((i * 1.0 * samplingFrequency) / samples);
break;
    }
    Serial.print(abscissa, 6);
    Serial.print(" ");
    Serial.print(vData[i], 4);
    Serial.println();
  }
  Serial.println();
}
--------

Valori piu' grandi di 128 nel numero di samples generano un errore di out_of_memory

Suonando su una tastiera musicale la quinta ottava ho acquisito i dati e trascitto il valore di massimo picco



Come si vede i valori di frequenza calcolati sono molto differenti da quelli teorici ma si osservi che il rapporto di frequenza tra due note consecutive distante due semitoni e' molto prossimo al valore teorico di 1.1225. Inoltre il rapporto tra la frequenza teorica e quella calcolata e' sempre di circa 2.1 quindi puo' trattarsi della prima armonica superiore

Eseguendo la stessa prova ma sulla 4° ottava i risultati sono i seguenti


Con questo sketch le classi di frequenza hanno una larghezza di 75 Hz...quindi non e' comunque un sistema da usare come accordatore

In generale e' comunque un sistema che funziona bene nell'ambito delle frequenze udibili

Aruco Tag e filtri Kalman

Usando gli Aruco tag in ambiente esterno con illuminazione solare a diverse ore e in diversi periodi dell'anno ho trovato un errore nell...