mercoledì 2 gennaio 2019

Arduino GPS Datalogger

Ho provato a riconvertire un vecchio progetto in un GPS Datalogger
Lo shield aggiunto presenta un lettore SD Card ed un modulo DS1307 con il GPS collegato su Software Serial


I principali problemi:
1) pur acquisendo a 9600 dalla seriale ho scoperto che la scrittura della SD Card e' piu' lenta ..da questo la necessita' di fare un buffer. La scrittura di un blocco di byte e' molto piu' veloce di aprire il file in append, scrivere il byte, chiudere il file

2) il nome del file di acquisizione (che viene creato sulla base del tempo acquisito dall'RTC del DS1307) deve essere nel formato 8+3 del vecchio MSDOS (nel mio caso ho preferito usare due caratteri per mese, due carattteri per giorni, due caratteri per ora ed infine due caratteri per i minuti di inizio acquisizione)

3) questo semplice script segnala comunque che la memoria dell'Arduino e' ad limite critico

non ho ancora provato la funzione di deep sleep

--------------------------------------------------------------------------------------
// Low Power header
#include "LowPower.h"

// RTC headers
#include <Wire.h>
#include "RTClib.h"

// SD Card headers
#include <SPI.h>
#include <SD.h>

// Seriale dove invia il GPS
#include <SoftwareSerial.h>


RTC_DS1307 rtc;

const unsigned long SECOND = 1000;
const unsigned long HOUR = 3600 * SECOND;

unsigned long contatore = 0;
const unsigned int dim_buffer = 250;
byte SerialData[dim_buffer]; 

Sd2Card card;
SdVolume volume;
SdFile root;

const int chipSelect = 10;
char incomingByte = 0;   // for incoming serial data

char filen[10];
String filename;


// impostazione della seriale secondaria del GPS
SoftwareSerial mySerial(8, 9); // RX, TX

void setup() {
  Serial.begin(9600);
  while (!Serial) {
  }

  // inizializzazione RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  // Inizializzazione SD
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    while (1);
  }

  mySerial.begin(9600);

  contatore = 0;

  Serial.println("Inizializzazione terminata.");
}

void loop() {

  DateTime now = rtc.now();
  
  sprintf(filen, "%02d%02d%02d%02d.txt", now.month(), now.day(), now.hour(), now.minute());
  String filename(filen);
  delay(2500);

  for (int i=0; i <= 100000; i++){
        contatore = 0;
        while (mySerial.available()) {
            SerialData[contatore] = mySerial.read();
            contatore++;
          }

      
        File dataFile = SD.open(filename, FILE_WRITE);
            if (dataFile) {
              for (int s=0; s < contatore; s++){
                  dataFile.print(char(SerialData[s]));
              }
              dataFile.close();
            }
          
  }
  Serial.println("Finita acquisizione");

  //entra in sleep mode
  delay(HOUR);
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,SPI_OFF, USART0_OFF, TWI_OFF);

}

Moltipicazioni con logaritmi

Un tuffo nel passato del calcolo: moltiplicazioni con i logaritmi.



Una proprieta' dei logaritmi e' che una moltiplicazione di due numeri puo' essere effettuata come somma dei rispettivi logaritmi. Questa proprieta' e' usata nei regoli calcolatori ma si inizia con un esempio da un libro dei logaritmi dove sono tabulati (precalcolati) il valore dei logaritmi

Un esempio : calcolare 44 x 36

Dalle tavole si ricava la mantissa dei due numeri. Si legge che la mantissa di 44 e' pari a 64345 mentre la mantissa di 36 e' 55630.  Visto che 44 e 36 sono numeri a due cifre la caratteristica del logaritmo e' pari a 1. (per esempio tra 44,440 e 4400 cambia solo la parte caratteristica mentre la mantissa del logaritmo rimane sempre uguale...ovviamente in base 10)

Per moltiplicare i due numeri si possono sommare quindi 1.64345 e 1.55630 per un risultato di 3.19975.




A questo punto si deve calcolare il numero per il quale il logaritmo e' pari a 19974. Dalle tavole si trova che la mantissa 19976 corrisponde al numero 1584. Dal calcolo della somma il risultato deve essere a 4 cifre (parte caratteristica pari a 3) quindi il risultato e' compreso tra 1000 e 9999
Dalle tavole sembra che il risultato della nostra moltiplicazione sia di poco maggiore di 1584 (tipo 1584.1) ma si tratta di un problema di approssimazione delle tavole. Il risultato della  moltiplicazione di due interi  e' a sua volta un intero. Quindi il risultato di 44x36=1584


Si passa quindi al regolo calcolatore
Usando il cursore si allineano i valori 4.4 su D e 3.6 su CL. Si legge il risultato 1.58x guardando l'indice 1 di C su D




Usando un regolo calcolatore si puo' spostare l'indice 10 della scala C sul valore di 4.4 su D. Con il cursore ci si sposta sul valore 3.6 su C e si legge il risultato 1.58x su D. Dato che in 36x44 le ultime cifre sono 6 e 4 la cifra meno significativa e' 4 (6x4=24) per cui il risultato e' 1.584 ..rimane solo da sistemare la virgola



Lens Flare

Stamani ho provato a fotografare la Luna e Venere molto vicine nella stessa porzione di cielo con un iPhone SE
Questa e' la foto ripresa dalla camera del telefono


Mi sono accorto subito che ci sono troppi punti luminosi (la Luna e Venere sono poco sopra il centro dell'immagine)
Iphone oltre all'immagine registra anche un piccolo video per scegliere la posa migliore


Si vede chiaramente che due punti seguono i movimenti della camera muovendosi intorno al centro dell'immagine. Si tratta dei due riflessi dei lampioni all'interno dell'obbiettivo per un fenomeno conosciuto come lens flare


questa e' l'immagine del cielo senza i lampioni


venerdì 28 dicembre 2018

Scrivere Json File in ElectronJS

Un esempio di come salvare i dati in formato JSon in un progetto ElectronJS

Prima viene creato un nuovo oggetto vuoto e successivamente si inseriscono le coppie chiave-valore per popolare l'oggetto, l'oggetto viene poi convertito in una stringa Json con stringify ed infine la stringa viene salvata sul filesystem

===============================================================
      var sinkhole = {};
      sinkhole.localita = sessionStorage.getItem("localita");
      sinkhole.comune = sessionStorage.getItem("comune");
      sinkhole.data = sessionStorage.getItem("data");
      sinkhole.ora = sessionStorage.getItem("ora");
      sinkhole.compilatore = sessionStorage.getItem("compilatore");
      sinkhole.annotazioni = sessionStorage.getItem("annotazioni");
      sinkhole.nord = sessionStorage.getItem("nord");
      sinkhole.est = sessionStorage.getItem("est");
      sinkhole.sistema = sessionStorage.getItem("sistema");

      sinkhole.diametro = diametro;
      sinkhole.deformazione = deformazione;
      sinkhole.pericolo = pericolo;
      sinkhole.elemento = elemento;
      
      var esportazione = JSON.stringify(sinkhole);

      const fs = require('fs');
      var nome_file = sessionStorage.getItem("comune")+"_"+sessionStorage.getItem("ora")+".json";
      fs.writeFile(nome_file, esportazione, (err) => {
        if(err){
            alert("An error ocurred creating the file "+ err.message)
        }
        else {
          alert("File salvato come " + nome_file);
        }
      });

giovedì 27 dicembre 2018

DynamoDB con NodeJS

per prima cosa si installa nel progetto AWS SDK per NodeJS con

npm install aws-sdk
si lancia poi DynamoDB in locale come visto qui 
per fare  il deploy sui server Amazon del DB si deve decommentare la riga evidenziata in giallo

=========================================================
var AWS = require("aws-sdk");

AWS.config.update({region: "us-west-1",endpoint: "http://localhost:8000"});

// per fare il deploy su DynamoDB sui server Amazon
//AWS.config.update({endpoint: "https://dynamodb.us-west-2.amazonaws.com"});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Informazioni",
    KeySchema: [
        { AttributeName: "indice", KeyType: "HASH"},  //Partition key
        { AttributeName: "title", KeyType: "RANGE" }  //Sort key
    ],
    AttributeDefinitions: [
        { AttributeName: "indice", AttributeType: "N" },
        { AttributeName: "title", AttributeType: "S" }
    ],
    ProvisionedThroughput: {
        ReadCapacityUnits: 10,
        WriteCapacityUnits: 10
    }
};



dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("Unable to create table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Created table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});


//////////// INSERT ////////////////////////
var docClient = new AWS.DynamoDB.DocumentClient();
var table = "Informazioni";
var indice = 2015;
var title = "Il nome della rosa";

var params = {
    TableName:table,
    Item:{
        "indice": indice,
        "title": title,
    }
};

console.log("Adding a new item...");
docClient.put(params, function(err, data) {
    if (err) {
        console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Added item:", JSON.stringify(data, null, 2));
    }
});

//////////// QUERY ////////////////////////
var params = {
    TableName : table,
    KeyConditionExpression: "#yr = :yyyy",
    ExpressionAttributeNames:{
        "#yr": "indice"
    },
    ExpressionAttributeValues: {
        ":yyyy": 2015
    }
};

docClient.query(params, function(err, data) {
    if (err) {
        console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
    } else {
        console.log("Query succeeded.");
        data.Items.forEach(function(item) {
            console.log(" -", item.indice + ": " + item.title);
        });
    }
});



//////////// DELETE ITEM ////////////////////////
var params = {
    TableName:table,
    Key:{
        "indice": indice,
        "title": title
    },
    ConditionExpression:"indice <= :val",
    ExpressionAttributeValues: {
        ":val": 2016
    }
};

console.log("Attempting a conditional delete...");
docClient.delete(params, function(err, data) {
    if (err) {
        console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
    }
});


var params = {
    TableName : table
};

//////////// DELETE TABLE////////////////////////

dynamodb.deleteTable(params, function(err, data) {
    if (err) {
        console.error("Unable to delete table. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Deleted table. Table description JSON:", JSON.stringify(data, null, 2));
    }
});

Electron Packager

Mediante Electron Packager si possono creare dei pacchetti nativi per Linux, Windows e Mac OSX usando una sola piattaforma di sviluppo (nel mio caso una Linux Box)

Electron Packager si  installa con

npm install electron-packager -g

Per creare i pacchetti Windows in una Linux Box si deve prima installare Wine in modalita' 32 e 64 bit (attezione a questo ultimo aspetto)

Windows 64 bit
electron-packager . sinkholes_electron --overwrite --asar=true --platform=win32 --arch=x64  --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName="Sinkholes ElectronJs"

Windows 32 bit
electron-packager . sinkholes_electron --overwrite --asar=true --platform=win32 --arch=ia32  --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName="Sinkholes ElectronJs"

Mac OsX
electron-packager . --overwrite --platform=darwin --arch=x64  --prune=true --out=release-builds

Linux 64
electron-packager . electron-tutorial-app --overwrite --asar=true --platform=linux --arch=x64  --prune=true --out=release-builds

Per creare pacchetti senza asar si deve usare --no-asar (al contrario di come verrebbe naturale --asar=false)


mercoledì 26 dicembre 2018

Aumentare la RAM su Lenovo T440S

Per prima cosa c'e' da indicare che il Lenovo T440S monta 4 Gb di Ram saldati direttamente su scheda madre e c'e' un solo slot di espansione. In secondo luogo e' importante scegliere delle memoria DDR3 1600 a 1.35 V e non le piu' comuni 1.5 V

Lo smontaggio dello chassis prevede la completa rimozione del fondo...questo e' ad incastro e dopo aver tolto le viti si deve procedere a far saltare i fermi uno ad uno con un plettro di plastica. Attenzione operazione delicata




Change Detection with structural similarity

L'idea di base e' quella di cercare le differenze tra le due immagini sottostanti Non e' immediatamente visibile ma ci sono dei ...